library(ggplot2)
library(plyr)
library(dplyr)

Attaching package: <U+393C><U+3E31>dplyr<U+393C><U+3E32>

The following objects are masked from <U+393C><U+3E31>package:plyr<U+393C><U+3E32>:

    arrange, count, desc, failwith, id, mutate, rename, summarise, summarize

The following objects are masked from <U+393C><U+3E31>package:stats<U+393C><U+3E32>:

    filter, lag

The following objects are masked from <U+393C><U+3E31>package:base<U+393C><U+3E32>:

    intersect, setdiff, setequal, union
library(corrplot)
corrplot 0.84 loaded
library(caret)
Loading required package: lattice
library(gridExtra)

Attaching package: <U+393C><U+3E31>gridExtra<U+393C><U+3E32>

The following object is masked from <U+393C><U+3E31>package:dplyr<U+393C><U+3E32>:

    combine
library(scales)
library(Rmisc)
library(ggrepel)
library(psych)

Attaching package: <U+393C><U+3E31>psych<U+393C><U+3E32>

The following objects are masked from <U+393C><U+3E31>package:scales<U+393C><U+3E32>:

    alpha, rescale

The following objects are masked from <U+393C><U+3E31>package:ggplot2<U+393C><U+3E32>:

    %+%, alpha
                  ################################# Reading in data and combining training and test data ########################################
#read files
train=read.csv("./inputs/train.csv", stringsAsFactors=FALSE)
test=read.csv("./inputs/test.csv", stringsAsFactors=FALSE)
#check read in files
print(train)
print(test)
#remove id from both train and test variables
train=train[,-1]
print(train)
test=test[,-1]
print(test)
#combine train and test sets for analysis and cleaning
#test set has missing saleprice (uneqal dimension for merging with train set)
#make a copy of the test set before adding the extra column
test_tmp=test
test_tmp$SalePrice= NA
print(test_tmp)
#combine the added-column test set with the train set
all=rbind(train,test_tmp)
print(all)
#finding the number of numeric codes
numericVars=which(sapply(all, is.numeric))
numericVarNames=names(numericVars)
sprintf("There are %s numeric variables", length(numericVars))
[1] "There are 37 numeric variables"
                ######################################### Tabulate the number of missing values ####################################################
#tabulate the number of missing values
miss_freq=sort(colSums(is.na(all)),decreasing=TRUE)
print(miss_freq)
       PoolQC   MiscFeature         Alley         Fence     SalePrice   FireplaceQu   LotFrontage 
         2909          2814          2721          2348          1459          1420           486 
  GarageYrBlt  GarageFinish    GarageQual    GarageCond    GarageType      BsmtCond  BsmtExposure 
          159           159           159           159           157            82            82 
     BsmtQual  BsmtFinType2  BsmtFinType1    MasVnrType    MasVnrArea      MSZoning     Utilities 
           81            80            79            24            23             4             2 
 BsmtFullBath  BsmtHalfBath    Functional   Exterior1st   Exterior2nd    BsmtFinSF1    BsmtFinSF2 
            2             2             2             1             1             1             1 
    BsmtUnfSF   TotalBsmtSF    Electrical   KitchenQual    GarageCars    GarageArea      SaleType 
            1             1             1             1             1             1             1 
   MSSubClass       LotArea        Street      LotShape   LandContour     LotConfig     LandSlope 
            0             0             0             0             0             0             0 
 Neighborhood    Condition1    Condition2      BldgType    HouseStyle   OverallQual   OverallCond 
            0             0             0             0             0             0             0 
    YearBuilt  YearRemodAdd     RoofStyle      RoofMatl     ExterQual     ExterCond    Foundation 
            0             0             0             0             0             0             0 
      Heating     HeatingQC    CentralAir     X1stFlrSF     X2ndFlrSF  LowQualFinSF     GrLivArea 
            0             0             0             0             0             0             0 
     FullBath      HalfBath  BedroomAbvGr  KitchenAbvGr  TotRmsAbvGrd    Fireplaces    PavedDrive 
            0             0             0             0             0             0             0 
   WoodDeckSF   OpenPorchSF EnclosedPorch    X3SsnPorch   ScreenPorch      PoolArea       MiscVal 
            0             0             0             0             0             0             0 
       MoSold        YrSold SaleCondition 
            0             0             0 
sprintf("There are %s columns of missing values", sum(miss_freq>0))
[1] "There are 35 columns of missing values"
            ######################################### To fix all 34 variables with missing values ################################################
  1. PoolQC: Pool quality

    Ex   Excellent
    Gd   Good
    TA   Average/Typical
    Fa   Fair
    NA   No Pool
#replace missing values in PoolQC
#According to the data description, PoolQC has Excellent, Good, Average, Fair and No Pool levels. NA represents No Pool.
all$PoolQC[is.na(all$PoolQC)]='No Pool'
#convert the variable to ordinal class
values=c("No Pool"=0,"Po"=1,"Fa"=2,"TA"=3,"Gd"=4,"Ex"=5)
all$PoolQC=as.integer(revalue(all$PoolQC,values))
The following `from` values were not present in `x`: Po, TA
class(all$PoolQC)
[1] "integer"
#assessing PoolQC with PoolArea
all[all$PoolQC==0 & all$PoolArea>0, c("PoolQC","PoolArea","OverallQual")]
#this indicates some error in filling up of the missing values. '0' indicates no pool yet another variable showing its pool area.
#here we assume pools exist for these houses but without quality ratings.
#we will replace these values with reference to "OverallQual" variable
#there are 10 ordinal categories in "OverallQual" and we resampled it into 5 categories to match with PoolQC range.
all[2421,"PoolQC"]=2
all[2504,"PoolQC"]=3
all[2600,"PoolQC"]=2
  1. MiscFeature: Miscellaneous feature not covered in other categories

    Elev Elevator
    Gar2 2nd Garage (if not described in garage section)
    Othr Other
    Shed Shed (over 100 SF)
    TenC Tennis Court
    NA   None
#Replace missing values in MiscFeature
#MiscFeature account for the additional facilities that a house might possess, such as elevator, 2nd Gararge, Shed, Tennis Court and Others.
#The NAs are due to the house having no other additional facilities
#replacing 'NA' with 'None' and this feature should bein factor form.
all$MiscFeature[is.na(all$MiscFeature)]='None'
#convert the variable to factor class
all$MiscFeature=as.factor(all$MiscFeature)
class(all$MiscFeature)
[1] "factor"
  1. Alley: Type of alley access to property

    Grvl Gravel
    Pave Paved
    NA   No alley access
#NA represent no alley access
all$Alley[is.na(all$Alley)]='No alley access'
#convert the variable to factor class
all$Alley=as.factor(all$Alley)
class(all$Alley)
[1] "factor"
  1. Fence: Fence quality

    GdPrv    Good Privacy
    MnPrv    Minimum Privacy
    GdWo Good Wood
    MnWw Minimum Wood/Wire
    NA   No Fence
#NA represents No Fence
all$Fence[is.na(all$Fence)]='No Fence'
#converting this to factor class
all$Fence=as.factor(all$Fence)
class(all$Fence)
[1] "factor"
  1. FireplaceQu: Fireplace quality

    Ex   Excellent - Exceptional Masonry Fireplace
    Gd   Good - Masonry Fireplace in main level
    TA   Average - Prefabricated Fireplace in main living area or Masonry Fireplace in basement
    Fa   Fair - Prefabricated Fireplace in basement
    Po   Poor - Ben Franklin Stove
    NA   No Fireplace
#replace NA with no Fireplace
all$FireplaceQu[is.na(all$FireplaceQu)]="No Fireplace"
#another variable that is closely related to FireplaceQu is Fireplaces
#and let's check whether the number of houses with no fireplace in "Fireplaces" equates with the count in "FireplaceQu"
sprintf("The number of No Fireplace in variables FireplaceQu and Fireplaces are equal: %s",sum(all$FireplaceQu=="No Fireplace") == sum(all$Fireplaces==0))
[1] "The number of No Fireplace in variables FireplaceQu and Fireplaces are equal: TRUE"
#convert the variable to ordinal class
values=c("No Fireplace"=0,"Po"=1,"Fa"=2,"TA"=3,"Gd"=4,"Ex"=5)
all$FireplaceQu=as.integer(revalue(all$FireplaceQu,values))
class(all$FireplaceQu)
[1] "integer"
  1. LotFrontage: Linear feet of street connected to property

    Neighborhood: Physical locations within Ames city limits

    Blmngtn  Bloomington Heights
    Blueste  Bluestem
    BrDale   Briardale
    BrkSide  Brookside
    ClearCr  Clear Creek
    CollgCr  College Creek
    Crawfor  Crawford
    Edwards  Edwards
    Gilbert  Gilbert
    IDOTRR   Iowa DOT and Rail Road
    MeadowV  Meadow Village
    Mitchel  Mitchell
    Names    North Ames
    NoRidge  Northridge
    NPkVill  Northpark Villa
    NridgHt  Northridge Heights
    NWAmes   Northwest Ames
    OldTown  Old Town
    SWISU    South & West of Iowa State University
    Sawyer   Sawyer
    SawyerW  Sawyer West
    Somerst  Somerset
    StoneBr  Stone Brook
    Timber   Timberland
    Veenker  Veenker
#get the index for the rows with missing values
Lot_NAs=all[is.na(all$LotFrontage),c("Neighborhood","LotFrontage")]
print(Lot_NAs)
idx=as.numeric(rownames(Lot_NAs))
print(class(idx))
[1] "numeric"
print(length(idx))
[1] 486
# #we will use the mean distance of each "Neighbourhood" to replace the missing values in "LotFrontage"
for (i in idx){
      if(is.na(all$LotFrontage[i])){
              all[i,"LotFrontage"]=as.integer(mean(all$LotFrontage[all$Neighborhood==all[i,"Neighborhood"]], na.rm=TRUE))
        }
}
print(all[c(8,13,15,17),"LotFrontage"])
[1] 81 74 75 75
print(class(all$LotFrontage))
[1] "integer"
  1. GarageYrBlt: Year garage was built
#associate houses with missing values in this column as houses that did not rebuild or remodel its garage.
#replace this missing values with the year the house is built.
all[is.na(all$GarageYrBlt),"GarageYrBlt"]=all$YearBuilt[is.na(all$GarageYrBlt)]
class(all$GarageYrBlt)
[1] "integer"
#check whether the values have been replaced
sum(is.na(all$GarageYrBlt))
[1] 0

Putting all variables related to garage together:

Number of missing values in garag-related components:

GarageFinish: Interior finish of the garage = 159 GarageQual: Garage quality = 159 GarageCond: Garage condition = 159 GarageType: Garage location = 157 GarageCars: Size of garage in car capacity = 1 GarageArea: Size of garage in square feet = 1

#GarageFinish, GarageQual, GarageCond, GarageType, GarageCars and GarageArea seems to be inter-related.
tmp=all[is.na(all$GarageFinish) & is.na(all$GarageQual) & is.na(all$GarageCond) & is.na(all$GarageType),]
sprintf("how many of these rows have NA values in GarageFinish, Qual, Cond, and Type: %s", dim(tmp)[1])
[1] "how many of these rows have NA values in GarageFinish, Qual, Cond, and Type: 157"
#the above result indicates the the 157 missing values found in GarageType is also found in GarageFinish, Quala and Cond
#
all[is.na(all$GarageFinish) & is.na(all$GarageQual) & is.na(all$GarageCond) & !is.na(all$GarageType), c("GarageFinish","GarageQual","GarageCond","GarageType","GarageCars","GarageArea")]
#all[is.na(all$GarageCars) | is.na(all$GarageArea), c("GarageFinish","GarageQual","GarageCond","GarageType","GarageCars","GarageArea")]
  1. GarageCars: Size of garage in car capacity
  2. GarageArea: Size of garage in square feet
# the record 2127 seems to have a garage as it has value for GarageCars and GarageArea
# on the other hand, 2577 does not seem to have a garage
# lets fix these two entries first
# function: finding mode
getmode <- function(v) {
   uniqv <- unique(v)
   uniqv[which.max(tabulate(match(v, uniqv)))]
}
# entry 2127
all[2127,"GarageFinish"]=getmode(all$GarageFinish)
all[2127,"GarageQual"]=getmode(all$GarageQual)
all[2127,"GarageCond"]=getmode(all$GarageCond)
# entry 2577
all[2577,"GarageType"]=NA
all[2577,"GarageCars"]=0
all[2577,"GarageArea"]=0
#check the rectification
print(all[c(2127,2577),c("GarageFinish","GarageQual","GarageCond","GarageType","GarageCars","GarageArea")])
tmp=all[is.na(all$GarageFinish) & is.na(all$GarageQual) & is.na(all$GarageCond) & is.na(all$GarageType),]
sprintf("how many of these rows have NA values in GarageFinish, Qual, Cond, and Type (after replacement): %s", dim(tmp)[1])
[1] "how many of these rows have NA values in GarageFinish, Qual, Cond, and Type (after replacement): 158"
  1. GarageFinish: Interior finish of the garage

    Fin Finished RFn Rough Finished
    Unf Unfinished NA No Garage

#the NAs indicate "No Garage"
#replace NAs with "No Garage"
all[is.na(all$GarageFinish),"GarageFinish"]="No Garage"
#check the number of NAs again
sum(is.na(all$GarageFinish))
[1] 0
# convert this variable to ordinal
values=c('No Garage'=0, 'Unf'=1, 'RFn'=2, 'Fin'=3)
all$GarageFinish=as.integer(revalue(all$GarageFinish, values))
class(all$GarageFinish)
[1] "integer"
  1. GarageQual: Garage quality

    Ex Excellent Gd Good TA Typical/Average Fa Fair Po Poor NA No Garage

#the NAs indicate "No Garage"
#replace NAs with "No Garage"
all[is.na(all$GarageQual),"GarageQual"]="No Garage"
#check the number of NAs again
sum(is.na(all$GarageQual))
[1] 0
#convert to ordinal
values=c("No Garage"=0,"Po"=1,"Fa"=2,"TA"=3,"Gd"=4,"Ex"=5)
all$GarageQual=as.integer(revalue(all$GarageQual, values))
class(all$GarageQual)
[1] "integer"
  1. GarageCond: Garage condition

    Ex Excellent Gd Good TA Typical/Average Fa Fair Po Poor NA No Garage

#the NAs indicate "No Garage"
#replace NAs with "No Garage"
all[is.na(all$GarageCond),"GarageCond"]="No Garage"
#convert to ordinal
values=c("No Garage"=0,"Po"=1,"Fa"=2,"TA"=3,"Gd"=4,"Ex"=5)
all$GarageCond=as.integer(revalue(all$GarageCond, values))
class(all$GarageCond)
[1] "integer"
  1. GarageType: Garage location

    2Types More than one type of garage Attchd Attached to home Basment Basement Garage BuiltIn Built-In (Garage part of house - typically has room above garage) CarPort Car Port Detchd Detached from home NA No Garage

#the NAs indicate "No Garage"
#replace NAs with "No Garage"
all[is.na(all$GarageType),"GarageType"]="No Garage"
#convert to factor class
all$GarageType=as.factor(all$GarageType)
class(all$GarageType)
[1] "factor"

Putting all variables related to basement together:

No. of missing values in each variable:

BsmtCond: Evaluates the general condition of the basement = 82 BsmtExposure: Refers to walkout or garden level walls = 82
BsmtQual: Evaluates the height of the basement = 81 BsmtFinType2: Rating of basement finished area = 80 BsmtFinType1: Rating of basement finished area = 79 BsmtFullBath: Basement full bathrooms = 2 BsmtHalfBath: Basement half bathrooms = 2 BsmtFinSF1: Type 1 finished square feet = 1 BsmtFinSF2: Type 2 finished square feet = 1 BsmtUnfSF: Unfinished square feet of basement area = 1 TotalBsmtSF: Total square feet of basement area = 1

#check whether the 79 records with missing values in BsmtFinType1 correspond with those in BsmtCond, Exposure, Qual and FinType2
tmp=all[is.na(all$BsmtFinType1) & is.na(all$BsmtCond) & is.na(all$BsmtExposure) & is.na(all$BsmtQual) & is.na(all$BsmtFinType2),]
print(tmp)
sprintf("There are %s rows with NAs in bsmtfintype1, bsmtcond, bsmtexposure, bsmtqual and bsmtfintype2 concurrently ",dim(tmp)[1])
[1] "There are 79 rows with NAs in bsmtfintype1, bsmtcond, bsmtexposure, bsmtqual and bsmtfintype2 concurrently "
#finding the other records with NA in the basement variables.
all[!is.na(all$BsmtFinType1) & (is.na(all$BsmtCond)|is.na(all$BsmtExposure)|is.na(all$BsmtQual)|is.na(all$BsmtFinType2)),c("BsmtFinType1","BsmtCond","BsmtExposure","BsmtQual","BsmtFinType2")]
#each row is observed to have a missing value out of five variables
#we will replace these NAs with the mode.
all[333,"BsmtFinType2"]=getmode(all$BsmtFinType2)
all[949,"BsmtExposure"]=getmode(all$BsmtExposure)
all[1488,"BsmtExposure"]=getmode(all$BsmtExposure)
all[2041,"BsmtCond"]=getmode(all$BsmtCond)
all[2186,"BsmtCond"]=getmode(all$BsmtCond)
all[2218,"BsmtQual"]=getmode(all$BsmtQual)
all[2219,"BsmtQual"]=getmode(all$BsmtQual)
all[2349,"BsmtExposure"]=getmode(all$BsmtExposure)
all[2525,"BsmtCond"]=getmode(all$BsmtCond)
all[c(333,949,1488,2041,2186,2218,2219,2349,2525),c("BsmtFinType1","BsmtCond","BsmtExposure","BsmtQual","BsmtFinType2")]
  1. BsmtCond: Evaluates the general condition of the basement

    Ex Excellent Gd Good TA Typical - slight dampness allowed Fa Fair - dampness or some cracking or settling Po Poor - Severe cracking, settling, or wetness NA No Basement

#the NAs indicate "No Basement"
#replace NAs with "No Basement"
all[is.na(all$BsmtCond),"BsmtCond"]="No Basement"
#convert to ordinal
values=c("No Basement"=0,"Po"=1,"Fa"=2,"TA"=3,"Gd"=4,"Ex"=5)
all$BsmtCond=as.integer(revalue(all$BsmtCond, values))
The following `from` values were not present in `x`: Ex
class(all$BsmtCond)
[1] "integer"
  1. BsmtExposure: Refers to walkout or garden level walls

    Gd Good Exposure Av Average Exposure (split levels or foyers typically score average or above)
    Mn Mimimum Exposure No No Exposure NA No Basement

#the NAs indicate "No Basement"
#replace NAs with "No Basement"
all[is.na(all$BsmtExposure),"BsmtExposure"]="No Basement"
#convert to ordinal
values=c("No Basement"=0,"No"=1,"Mn"=2,"Av"=3,"Gd"=4)
all$BsmtExposure=as.integer(revalue(all$BsmtExposure, values))
class(all$BsmtExposure)
[1] "integer"
  1. BsmtQual: Evaluates the height of the basement

    Ex Excellent (100+ inches) Gd Good (90-99 inches) TA Typical (80-89 inches) Fa Fair (70-79 inches) Po Poor (<70 inches NA No Basement

#the NAs indicate "No Basement"
#replace NAs with "No Basement"
all[is.na(all$BsmtQual),"BsmtQual"]="No Basement"
#convert to ordinal
values=c("No Basement"=0,"Po"=1,"Fa"=2,"TA"=3,"Gd"=4,"Ex"=5)
all$BsmtQual=as.integer(revalue(all$BsmtQual, values))
The following `from` values were not present in `x`: Po
class(all$BsmtQual)
[1] "integer"
  1. BsmtFinType2: Rating of basement finished area (if multiple types)

    GLQ Good Living Quarters ALQ Average Living Quarters BLQ Below Average Living Quarters
    Rec Average Rec Room LwQ Low Quality Unf Unfinshed NA No Basement

#the NAs indicate "No Basement"
#replace NAs with "No Basement"
all[is.na(all$BsmtFinType2),"BsmtFinType2"]="No Basement"
#convert to ordinal
values=c("No Basement"=0,"Unf"=1,"LwQ"=2,"Rec"=3,"BLQ"=4,"ALQ"=5,"GLQ"=6)
all$BsmtFinType2=as.integer(revalue(all$BsmtFinType2, values))
class(all$BsmtFinType2)
[1] "integer"
  1. BsmtFinTyp1: Rating of basement finished area

    GLQ Good Living Quarters ALQ Average Living Quarters BLQ Below Average Living Quarters
    Rec Average Rec Room LwQ Low Quality Unf Unfinshed NA No Basement

#the NAs indicate "No Basement"
#replace NAs with "No Basement"
all[is.na(all$BsmtFinType1),"BsmtFinType1"]="No Basement"
#convert to ordinal
values=c("No Basement"=0,"Unf"=1,"LwQ"=2,"Rec"=3,"BLQ"=4,"ALQ"=5,"GLQ"=6)
all$BsmtFinType1=as.integer(revalue(all$BsmtFinType1, values))
class(all$BsmtFinType1)
[1] "integer"
  1. BsmtFullBath: Basement full bathrooms
#replace NAs with zero
all[is.na(all$BsmtFullBath),"BsmtFullBath"]=0
hist(all$BsmtFullBath, main="Histogram of BsmtFullBath", xlab="number of full bathrooms in basement")

  1. BsmtHalfBath: Basement half bathrooms
#replace NAs with zero
all[is.na(all$BsmtHalfBath),"BsmtHalfBath"]=0
hist(all$BsmtHalfBath, main="Histogram of BsmtHalfBath", xlab="number of half bathrooms in basement")

  1. BsmtFinSF1: Type 1 finished square feet 22.BsmtFinSF2: Type 2 finished square feet
  2. BsmtUnfSF: Unfinished square feet of basement area
  3. TotalBsmtSF: Total square feet of basement area
#replace NAs with zero
#they are integers
all[is.na(all$BsmtFinSF1),"BsmtFinSF1"]=0
all[is.na(all$BsmtFinSF2),"BsmtFinSF2"]=0
all[is.na(all$BsmtUnfSF),"BsmtUnfSF"]=0
all[is.na(all$TotalBsmtSF),"TotalBsmtSF"]=0

Putting related variables, MasVnrType (24 missing values) and MasVnrArea(23 missing values), to assess.

#the number of records with MasVnrType being NA given MasVnrArea is also NA.
tmp=all[is.na(all$MasVnrType) & is.na(all$MasVnrArea),]
sprintf("The number of records with with MasVnrType being NA given MasVnrArea is also NA: %s", dim(tmp)[1])
[1] "The number of records with with MasVnrType being NA given MasVnrArea is also NA: 23"
#finding the extra NA record of MasVnrType
all[is.na(all$MasVnrType) & !is.na(all$MasVnrArea), c("MasVnrType","MasVnrArea")]
#correct entry 2611
table(all$MasVnrType)

 BrkCmn BrkFace    None   Stone 
     25     879    1742     249 
#"BrkFace" has the highest mode after "None"
all[2611,c("MasVnrType")]="BrkFace"
print(all[2611,c("MasVnrType","MasVnrArea")])
#replace NAs with None
all[is.na(all$MasVnrType),"MasVnrType"]="None"
  1. MasVnrType: Masonry veneer type

    BrkCmn Brick Common BrkFace Brick Face CBlock Cinder Block None None Stone Stone

#check the relationship between the different category in MasVnrType and SalePrice
attach(all)
aggregate(all[,c("MasVnrType","SalePrice")],by=list(MasVnrType),FUN=mean,na.rm=TRUE)
argument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NAargument is not numeric or logical: returning NA
#relationship seems to exist between "MasVnrType" and "SalePrice"
#convert to ordinal
values=c("BrkCmn"=0,"None"=1,"BrkFace"=2,"Stone"=3)
all$MasVnrType=as.integer(revalue(all$MasVnrType, values))
class(all$MasVnrType)
[1] "integer"
  1. MasVnrArea: Masonry veneer area in square feet
#replace NAs with zero
all[is.na(all$MasVnrArea),"MasVnrArea"]=0
  1. MSZoning: Identifies the general zoning classification of the sale.

    A Agriculture C Commercial FV Floating Village Residential I Industrial RH Residential High Density RL Residential Low Density RP Residential Low Density Park RM Residential Medium Density

#input missing values with mode and convert to factor
all[is.na(all$MSZoning),"MSZoning"]=getmode(all$MSZoning)
all$MSZoning=as.factor(all$MSZoning)
class(all$MSZoning)
[1] "factor"
  1. KitchenQual: Kitchen quality

    Ex Excellent Gd Good TA Typical/Average Fa Fair Po Poor

#replace missing values with the mode
all[is.na(all$KitchenQual),"KitchenQual"]=getmode(all$KitchenQual)
sprintf("number of missing values in KitchenQual(after replacement):%s", sum(is.na(all$KitchenQual)))
[1] "number of missing values in KitchenQual(after replacement):0"
#convert to ordinal
values=c("Po"=0,"Fa"=1,"TA"=2,"Gd"=3,"Ex"=4)
all$KitchenQual=as.integer(revalue(all$KitchenQual, values))
The following `from` values were not present in `x`: Po
class(all$KitchenQual)
[1] "integer"
  1. Utilities: Type of utilities available

    AllPub All public Utilities (E,G,W,& S)
    NoSewr Electricity, Gas, and Water (Septic Tank) NoSeWa Electricity and Gas Only ELO Electricity only

#checking the frequency of each level
table(all$Utilities)

AllPub NoSeWa 
  2916      1 
#the table shows that most of the rows are categorised as "AllPub"
#this variable hence serve little value in predicting the response varaiable
all$Utilities=NULL
  1. Functional: Home functionality (Assume typical unless deductions are warranted)

    Typ Typical Functionality Min1 Minor Deductions 1 Min2 Minor Deductions 2 Mod Moderate Deductions Maj1 Major Deductions 1 Maj2 Major Deductions 2 Sev Severely Damaged Sal Salvage only

#replace the missing value with the mode
all[is.na(all$Functional),"Functional"]=getmode(all$Functional)
#convert to ordinal
values=c("Sal"=0,"Sev"=1,"Maj2"=2,"Maj1"=3,"Mod"=4,"Min2"=5,"Min1"=6,"Typ"=7)
all$Functional=as.integer(revalue(all$Functional, values))
The following `from` values were not present in `x`: Sal
class(all$Functional)
[1] "integer"
table(all$Functional)

   1    2    3    4    5    6    7 
   2    9   19   35   70   65 2719 
#checking the distribution of the Functional
table(all$Functional)

   1    2    3    4    5    6    7 
   2    9   19   35   70   65 2719 
  1. Exterior1st: Exterior covering on house

    AsbShng Asbestos Shingles AsphShn Asphalt Shingles BrkComm Brick Common BrkFace Brick Face CBlock Cinder Block CemntBd Cement Board HdBoard Hard Board ImStucc Imitation Stucco MetalSd Metal Siding Other Other Plywood Plywood PreCast PreCast Stone Stone Stucco Stucco VinylSd Vinyl Siding Wd Sdng Wood Siding WdShing Wood Shingles

#replace missing values with the mode
all[is.na(all$Exterior1st),"Exterior1st"]=getmode(all$Exterior1st)
#convert as factor
all$Exterior1st= as.factor(all$Exterior1st)
class(all$Exterior1st)
[1] "factor"
  1. Exterior2nd: Exterior covering on house (if more than one material)

    AsbShng Asbestos Shingles AsphShn Asphalt Shingles BrkComm Brick Common BrkFace Brick Face CBlock Cinder Block CemntBd Cement Board HdBoard Hard Board ImStucc Imitation Stucco MetalSd Metal Siding Other Other Plywood Plywood PreCast PreCast Stone Stone Stucco Stucco VinylSd Vinyl Siding Wd Sdng Wood Siding WdShing Wood Shingles

#replace missing values with the mode
all[is.na(all$Exterior2nd),"Exterior2nd"]=getmode(all$Exterior2nd)
#convert as factor
all$Exterior2nd= as.factor(all$Exterior2nd)
class(all$Exterior2nd)
[1] "factor"

33.Electrical: Electrical system

   SBrkr    Standard Circuit Breakers & Romex
   FuseA    Fuse Box over 60 AMP and all Romex wiring (Average) 
   FuseF    60 AMP Fuse Box and mostly Romex wiring (Fair)
   FuseP    60 AMP Fuse Box and mostly knob & tube wiring (poor)
   Mix  Mixed
#replace missing value with mode and convert variable to factor
all[is.na(all$Electrical),"Electrical"]=getmode(all$Electrical)
all$Electrical=as.factor(all$Electrical)
class(all$Electrical)
[1] "factor"
table(all$Electrical)

FuseA FuseF FuseP   Mix SBrkr 
  188    50     8     1  2672 
  1. SaleType: Type of sale

    WD Warranty Deed - Conventional CWD Warranty Deed - Cash VWD Warranty Deed - VA Loan New Home just constructed and sold COD Court Officer Deed/Estate Con Contract 15% Down payment regular terms ConLw Contract Low Down payment and low interest ConLI Contract Low Interest ConLD Contract Low Down Oth Other

#replace missing value with mode and convert variable to factor
all[is.na(all$SaleType),"SaleType"]=getmode(all$SaleType)
all$SaleType=as.factor(all$SaleType)
class(all$SaleType)
[1] "factor"
table(all$SaleType)

  COD   Con ConLD ConLI ConLw   CWD   New   Oth    WD 
   87     5    26     9     8    12   239     7  2526 
              ################################### Convert the remaining variables to appropriate class #######################################
  1. Foundation: Type of foundation

    BrkTil   Brick & Tile
    CBlock   Cinder Block
    PConc    Poured Contrete 
    Slab Slab
    Stone    Stone
    Wood Wood
#converting into factor class
all$Foundation=as.factor(all$Foundation)
class(all$Foundation)
[1] "factor"
  1. Heating: Type of heating

    Floor    Floor Furnace
    GasA Gas forced warm air furnace
    GasW Gas hot water or steam heat
    Grav Gravity furnace 
    OthW Hot water or steam heat other than gas
    Wall Wall furnace
#converting into factor class
all$Heating=as.factor(all$Heating)
class(all$Heating)
[1] "factor"
  1. HeatingQC: Heating quality and condition

    Ex   Excellent
    Gd   Good
    TA   Average/Typical
    Fa   Fair
    Po   Poor
#converting into ordinal
values=c("Po"=0,"Fa"=1,"TA"=2,"Gd"=3,"Ex"=4)
all$HeatingQC=as.integer(revalue(all$HeatingQC, values))
class(all$HeatingQC)
[1] "integer"
  1. CentralAir: Central air conditioning

    N    No
    Y    Yes
#convert to ordinal
values=c("N"=0,"Y"=1)
all$CentralAir=as.integer(revalue(all$CentralAir, values))
class(all$CentralAir)
[1] "integer"
  1. RoofStyle: Type of roof

    Flat Flat
    Gable    Gable
    Gambrel  Gabrel (Barn)
    Hip  Hip
    Mansard  Mansard
    Shed Shed
#converting into factor class
all$RoofStyle=as.factor(all$RoofStyle)
class(all$RoofStyle)
[1] "factor"

f.RoofMatl: Roof material

   ClyTile  Clay or Tile
   CompShg  Standard (Composite) Shingle
   Membran  Membrane
   Metal    Metal
   Roll Roll
   Tar&Grv  Gravel & Tar
   WdShake  Wood Shakes
   WdShngl  Wood Shingles
#converting into factor class
all$RoofMatl=as.factor(all$RoofMatl)
class(all$RoofMatl)
[1] "factor"
  1. LandContour: Flatness of the property

    Lvl  Near Flat/Level 
    Bnk  Banked - Quick and significant rise from street grade to building
    HLS  Hillside - Significant slope from side to side
    Low  Depression
#converting into factor class
all$LandContour=as.factor(all$LandContour)
class(all$LandContour)
[1] "factor"

h.LandSlope: Slope of property

   Gtl  Gentle slope
   Mod  Moderate Slope  
   Sev  Severe Slope
#converting to ordinal
values=c("Sev"=0,"Mod"=1,"Gtl"=2)
all$LandSlope=as.integer(revalue(all$LandSlope, values))
class(all$LandSlope)
[1] "integer"
  1. BldgType: Type of dwelling

    1Fam Single-family Detached  
    2FmCon   Two-family Conversion; originally built as one-family dwelling
    Duplx    Duplex
    TwnhsE   Townhouse End Unit
    TwnhsI   Townhouse Inside Unit
#convert to factor
all$BldgType=as.factor(all$BldgType)
class(all$BldgType)
[1] "factor"
  1. HouseStyle: Style of dwelling

    1Story   One story
    1.5Fin   One and one-half story: 2nd level finished
    1.5Unf   One and one-half story: 2nd level unfinished
    2Story   Two story
    2.5Fin   Two and one-half story: 2nd level finished
    2.5Unf   Two and one-half story: 2nd level unfinished
    SFoyer   Split Foyer
    SLvl Split Level
#convert to factor
all$HouseStyle=as.factor(all$HouseStyle)
class(all$HouseStyle)
[1] "factor"
  1. Neighborhood: Physical locations within Ames city limits

    Blmngtn  Bloomington Heights
    Blueste  Bluestem
    BrDale   Briardale
    BrkSide  Brookside
    ClearCr  Clear Creek
    CollgCr  College Creek
    Crawfor  Crawford
    Edwards  Edwards
    Gilbert  Gilbert
    IDOTRR   Iowa DOT and Rail Road
    MeadowV  Meadow Village
    Mitchel  Mitchell
    Names    North Ames
    NoRidge  Northridge
    NPkVill  Northpark Villa
    NridgHt  Northridge Heights
    NWAmes   Northwest Ames
    OldTown  Old Town
    SWISU    South & West of Iowa State University
    Sawyer   Sawyer
    SawyerW  Sawyer West
    Somerst  Somerset
    StoneBr  Stone Brook
    Timber   Timberland
    Veenker  Veenker
#convert to factor
all$Neighborhood=as.factor(all$Neighborhood)
class(all$Neighborhood)
[1] "factor"
  1. Condition1: Proximity to various conditions

    Artery   Adjacent to arterial street
    Feedr    Adjacent to feeder street   
    Norm Normal  
    RRNn Within 200' of North-South Railroad
    RRAn Adjacent to North-South Railroad
    PosN Near positive off-site feature--park, greenbelt, etc.
    PosA Adjacent to postive off-site feature
    RRNe Within 200' of East-West Railroad
    RRAe Adjacent to East-West Railroad
#convert to factor
all$Condition1=as.factor(all$Condition1)
class(all$Condition1)
[1] "factor"
  1. Condition2: Proximity to various conditions (if more than one is present)

    Artery   Adjacent to arterial street
    Feedr    Adjacent to feeder street   
    Norm Normal  
    RRNn Within 200' of North-South Railroad
    RRAn Adjacent to North-South Railroad
    PosN Near positive off-site feature--park, greenbelt, etc.
    PosA Adjacent to postive off-site feature
    RRNe Within 200' of East-West Railroad
    RRAe Adjacent to East-West Railroad
#convert to factor
all$Condition2=as.factor(all$Condition2)
class(all$Condition2)
[1] "factor"
  1. Street: Type of road access to property

    Grvl Gravel  
    Pave Paved
#convert to ordinal
values=c("Grvl"=0,"Pave"=1)
all$Street=as.integer(revalue(all$Street, values))
class(all$Street)
[1] "integer"
  1. PavedDrive: Paved driveway

    Y    Paved 
    P    Partial Pavement
    N    Dirt/Gravel
#convert to ordinal
values=c("N"=0,"P"=1,"Y"=2)
all$PavedDrive=as.integer(revalue(all$PavedDrive, values))
class(all$PavedDrive)
[1] "integer"
  1. ExterQual: Evaluates the quality of the material on the exterior

    Ex   Excellent
    Gd   Good
    TA   Average/Typical
    Fa   Fair
    Po   Poor
#convert to ordinal
values=c("Po"=0,"Fa"=1,"TA"=2,"Gd"=3,"Ex"=4)
all$ExterQual=as.integer(revalue(all$ExterQual, values))
The following `from` values were not present in `x`: Po
class(all$ExterQual)
[1] "integer"
#check the distribution of the ordinal variable
table(all$ExterQual)

   1    2    3    4 
  35 1798  979  107 
  1. ExterCond: Evaluates the present condition of the material on the exterior

    Ex   Excellent
    Gd   Good
    TA   Average/Typical
    Fa   Fair
    Po   Poor
#convert to ordinal
values=c("Po"=0,"Fa"=1,"TA"=2,"Gd"=3,"Ex"=4)
all$ExterCond=as.integer(revalue(all$ExterCond, values))
class(all$ExterCond)
[1] "integer"
#check the distribution of the ordinal variable
table(all$ExterCond)

   0    1    2    3    4 
   3   67 2538  299   12 
  1. YrSold: Year Sold (YYYY)

  2. MoSold: Month Sold (MM)

#the prices of houses should be cheaper in earlier years.
#convert YrSold to ordinal
sprintf("Is data type of YrSold integer: %s", is.integer(YrSold))
[1] "Is data type of YrSold integer: TRUE"
#convert to factor
sprintf("Is data type of MoSold integer: %s", is.integer(MoSold))
[1] "Is data type of MoSold integer: TRUE"
all$MoSold=as.factor(all$MoSold)
class(all$MoSold)
[1] "factor"
  1. MSSubClass: Identifies the type of dwelling involved in the sale.

     20  1-STORY 1946 & NEWER ALL STYLES
     30  1-STORY 1945 & OLDER
     40  1-STORY W/FINISHED ATTIC ALL AGES
     45  1-1/2 STORY - UNFINISHED ALL AGES
     50  1-1/2 STORY FINISHED ALL AGES
     60  2-STORY 1946 & NEWER
     70  2-STORY 1945 & OLDER
     75  2-1/2 STORY ALL AGES
     80  SPLIT OR MULTI-LEVEL
     85  SPLIT FOYER
     90  DUPLEX - ALL STYLES AND AGES
    120  1-STORY PUD (Planned Unit Development) - 1946 & NEWER
    150  1-1/2 STORY PUD - ALL AGES
    160  2-STORY PUD - 1946 & NEWER
    180  PUD - MULTILEVEL - INCL SPLIT LEV/FOYER
    190  2 FAMILY CONVERSION - ALL STYLES AND AGES
#convert to factor
all$MSSubClass=as.factor(all$MSSubClass)
str(all$MSSubClass)
 Factor w/ 16 levels "20","30","40",..: 6 1 6 7 6 5 1 6 5 16 ...
  1. LotShape: General shape of property

    Reg  Regular 
    IR1  Slightly irregular
    IR2  Moderately Irregular
    IR3  Irregular
#convert LotShape as factor
values=c('IR3'=0, 'IR2'=1, 'IR1'=2, 'Reg'=3)
all$LotShape=as.integer(revalue(all$LotShape,values))
class(all$LotShape)
[1] "integer"
#check the distribution of the data
table(all$LotShape)

   0    1    2    3 
  16   76  968 1859 
  1. LotConfig: Lot configuration

    Inside   Inside lot
    Corner   Corner lot
    CulDSac  Cul-de-sac
    FR2  Frontage on 2 sides of property
    FR3  Frontage on 3 sides of property
#convert LotConfig as factor
all$LotConfig=as.factor(all$LotConfig)
class(all$LotConfig)
[1] "factor"

w.SaleCondition: Condition of sale

   Normal   Normal Sale
   Abnorml  Abnormal Sale -  trade, foreclosure, short sale
   AdjLand  Adjoining Land Purchase
   Alloca   Allocation - two linked properties with separate deeds, typically condo with a garage unit  
   Family   Sale between family members
   Partial  Home was not completed when last assessed (associated with New Homes)
#convert as factor
all$SaleCondition=as.factor(all$SaleCondition)
class(all$SaleCondition)
[1] "factor"
                ################################# Check the number of missing data and structure of the data  #####################################
#tabulate the number of missing values
miss_freq=sort(colSums(is.na(all)),decreasing=TRUE)
print(miss_freq)
    SalePrice    MSSubClass      MSZoning   LotFrontage       LotArea        Street         Alley 
         1459             0             0             0             0             0             0 
     LotShape   LandContour     LotConfig     LandSlope  Neighborhood    Condition1    Condition2 
            0             0             0             0             0             0             0 
     BldgType    HouseStyle   OverallQual   OverallCond     YearBuilt  YearRemodAdd     RoofStyle 
            0             0             0             0             0             0             0 
     RoofMatl   Exterior1st   Exterior2nd    MasVnrType    MasVnrArea     ExterQual     ExterCond 
            0             0             0             0             0             0             0 
   Foundation      BsmtQual      BsmtCond  BsmtExposure  BsmtFinType1    BsmtFinSF1  BsmtFinType2 
            0             0             0             0             0             0             0 
   BsmtFinSF2     BsmtUnfSF   TotalBsmtSF       Heating     HeatingQC    CentralAir    Electrical 
            0             0             0             0             0             0             0 
    X1stFlrSF     X2ndFlrSF  LowQualFinSF     GrLivArea  BsmtFullBath  BsmtHalfBath      FullBath 
            0             0             0             0             0             0             0 
     HalfBath  BedroomAbvGr  KitchenAbvGr   KitchenQual  TotRmsAbvGrd    Functional    Fireplaces 
            0             0             0             0             0             0             0 
  FireplaceQu    GarageType   GarageYrBlt  GarageFinish    GarageCars    GarageArea    GarageQual 
            0             0             0             0             0             0             0 
   GarageCond    PavedDrive    WoodDeckSF   OpenPorchSF EnclosedPorch    X3SsnPorch   ScreenPorch 
            0             0             0             0             0             0             0 
     PoolArea        PoolQC         Fence   MiscFeature       MiscVal        MoSold        YrSold 
            0             0             0             0             0             0             0 
     SaleType SaleCondition 
            0             0 
sprintf("There are %s columns of missing values", sum(miss_freq>0))
[1] "There are 1 columns of missing values"
#check the structure of the data
str(all)
'data.frame':   2919 obs. of  79 variables:
 $ MSSubClass   : Factor w/ 16 levels "20","30","40",..: 6 1 6 7 6 5 1 6 5 16 ...
 $ MSZoning     : Factor w/ 5 levels "C (all)","FV",..: 4 4 4 4 4 4 4 4 5 4 ...
 $ LotFrontage  : int  65 80 68 60 84 85 75 81 51 50 ...
 $ LotArea      : int  8450 9600 11250 9550 14260 14115 10084 10382 6120 7420 ...
 $ Street       : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Alley        : Factor w/ 3 levels "Grvl","No alley access",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ LotShape     : int  3 3 2 2 2 2 3 2 3 3 ...
 $ LandContour  : Factor w/ 4 levels "Bnk","HLS","Low",..: 4 4 4 4 4 4 4 4 4 4 ...
 $ LotConfig    : Factor w/ 5 levels "Corner","CulDSac",..: 5 3 5 1 3 5 5 1 5 1 ...
 $ LandSlope    : int  2 2 2 2 2 2 2 2 2 2 ...
 $ Neighborhood : Factor w/ 25 levels "Blmngtn","Blueste",..: 6 25 6 7 14 12 21 17 18 4 ...
 $ Condition1   : Factor w/ 9 levels "Artery","Feedr",..: 3 2 3 3 3 3 3 5 1 1 ...
 $ Condition2   : Factor w/ 8 levels "Artery","Feedr",..: 3 3 3 3 3 3 3 3 3 1 ...
 $ BldgType     : Factor w/ 5 levels "1Fam","2fmCon",..: 1 1 1 1 1 1 1 1 1 2 ...
 $ HouseStyle   : Factor w/ 8 levels "1.5Fin","1.5Unf",..: 6 3 6 6 6 1 3 6 1 2 ...
 $ OverallQual  : int  7 6 7 7 8 5 8 7 7 5 ...
 $ OverallCond  : int  5 8 5 5 5 5 5 6 5 6 ...
 $ YearBuilt    : int  2003 1976 2001 1915 2000 1993 2004 1973 1931 1939 ...
 $ YearRemodAdd : int  2003 1976 2002 1970 2000 1995 2005 1973 1950 1950 ...
 $ RoofStyle    : Factor w/ 6 levels "Flat","Gable",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ RoofMatl     : Factor w/ 8 levels "ClyTile","CompShg",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ Exterior1st  : Factor w/ 15 levels "AsbShng","AsphShn",..: 13 9 13 14 13 13 13 7 4 9 ...
 $ Exterior2nd  : Factor w/ 16 levels "AsbShng","AsphShn",..: 14 9 14 16 14 14 14 7 16 9 ...
 $ MasVnrType   : int  2 1 2 1 2 1 3 3 1 1 ...
 $ MasVnrArea   : num  196 0 162 0 350 0 186 240 0 0 ...
 $ ExterQual    : int  3 2 3 2 3 2 3 2 2 2 ...
 $ ExterCond    : int  2 2 2 2 2 2 2 2 2 2 ...
 $ Foundation   : Factor w/ 6 levels "BrkTil","CBlock",..: 3 2 3 1 3 6 3 2 1 1 ...
 $ BsmtQual     : int  4 4 4 3 4 4 5 4 3 3 ...
 $ BsmtCond     : int  3 3 3 4 3 3 3 3 3 3 ...
 $ BsmtExposure : int  1 4 2 1 3 1 3 2 1 1 ...
 $ BsmtFinType1 : int  6 5 6 5 6 6 6 5 1 6 ...
 $ BsmtFinSF1   : num  706 978 486 216 655 ...
 $ BsmtFinType2 : int  1 1 1 1 1 1 1 4 1 1 ...
 $ BsmtFinSF2   : num  0 0 0 0 0 0 0 32 0 0 ...
 $ BsmtUnfSF    : num  150 284 434 540 490 64 317 216 952 140 ...
 $ TotalBsmtSF  : num  856 1262 920 756 1145 ...
 $ Heating      : Factor w/ 6 levels "Floor","GasA",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ HeatingQC    : int  4 4 4 3 4 4 4 4 3 4 ...
 $ CentralAir   : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Electrical   : Factor w/ 5 levels "FuseA","FuseF",..: 5 5 5 5 5 5 5 5 2 5 ...
 $ X1stFlrSF    : int  856 1262 920 961 1145 796 1694 1107 1022 1077 ...
 $ X2ndFlrSF    : int  854 0 866 756 1053 566 0 983 752 0 ...
 $ LowQualFinSF : int  0 0 0 0 0 0 0 0 0 0 ...
 $ GrLivArea    : int  1710 1262 1786 1717 2198 1362 1694 2090 1774 1077 ...
 $ BsmtFullBath : num  1 0 1 1 1 1 1 1 0 1 ...
 $ BsmtHalfBath : num  0 1 0 0 0 0 0 0 0 0 ...
 $ FullBath     : int  2 2 2 1 2 1 2 2 2 1 ...
 $ HalfBath     : int  1 0 1 0 1 1 0 1 0 0 ...
 $ BedroomAbvGr : int  3 3 3 3 4 1 3 3 2 2 ...
 $ KitchenAbvGr : int  1 1 1 1 1 1 1 1 2 2 ...
 $ KitchenQual  : int  3 2 3 3 3 2 3 2 2 2 ...
 $ TotRmsAbvGrd : int  8 6 6 7 9 5 7 7 8 5 ...
 $ Functional   : int  7 7 7 7 7 7 7 7 6 7 ...
 $ Fireplaces   : int  0 1 1 1 1 0 1 2 2 2 ...
 $ FireplaceQu  : int  0 3 3 4 3 0 4 3 3 3 ...
 $ GarageType   : Factor w/ 7 levels "2Types","Attchd",..: 2 2 2 6 2 2 2 2 6 2 ...
 $ GarageYrBlt  : int  2003 1976 2001 1998 2000 1993 2004 1973 1931 1939 ...
 $ GarageFinish : int  2 2 2 1 2 1 2 2 1 2 ...
 $ GarageCars   : num  2 2 2 3 3 2 2 2 2 1 ...
 $ GarageArea   : num  548 460 608 642 836 480 636 484 468 205 ...
 $ GarageQual   : int  3 3 3 3 3 3 3 3 2 4 ...
 $ GarageCond   : int  3 3 3 3 3 3 3 3 3 3 ...
 $ PavedDrive   : int  2 2 2 2 2 2 2 2 2 2 ...
 $ WoodDeckSF   : int  0 298 0 0 192 40 255 235 90 0 ...
 $ OpenPorchSF  : int  61 0 42 35 84 30 57 204 0 4 ...
 $ EnclosedPorch: int  0 0 0 272 0 0 0 228 205 0 ...
 $ X3SsnPorch   : int  0 0 0 0 0 320 0 0 0 0 ...
 $ ScreenPorch  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ PoolArea     : int  0 0 0 0 0 0 0 0 0 0 ...
 $ PoolQC       : num  0 0 0 0 0 0 0 0 0 0 ...
 $ Fence        : Factor w/ 5 levels "GdPrv","GdWo",..: 5 5 5 5 5 3 5 5 5 5 ...
 $ MiscFeature  : Factor w/ 5 levels "Gar2","None",..: 2 2 2 2 2 4 2 4 2 2 ...
 $ MiscVal      : int  0 0 0 0 0 700 0 350 0 0 ...
 $ MoSold       : Factor w/ 12 levels "1","2","3","4",..: 2 5 9 2 12 10 8 11 4 1 ...
 $ YrSold       : int  2008 2007 2008 2006 2008 2009 2007 2009 2008 2008 ...
 $ SaleType     : Factor w/ 9 levels "COD","Con","ConLD",..: 9 9 9 9 9 9 9 9 9 9 ...
 $ SaleCondition: Factor w/ 6 levels "Abnorml","AdjLand",..: 5 5 5 1 5 5 5 5 1 5 ...
 $ SalePrice    : int  208500 181500 223500 140000 250000 143000 307000 200000 129900 118000 ...
#save dataframe with its formatting.
saveRDS(all,file="all_DP.rds")
LS0tDQp0aXRsZTogIkRhdGFfUHJlcGFyYXRpb24iDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGx5cikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KFJtaXNjKQ0KbGlicmFyeShnZ3JlcGVsKQ0KbGlicmFyeShwc3ljaCkNCmBgYA0KDQoNCiAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgUmVhZGluZyBpbiBkYXRhIGFuZCBjb21iaW5pbmcgdHJhaW5pbmcgYW5kIHRlc3QgZGF0YSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCg0KYGBge3J9DQojcmVhZCBmaWxlcw0KdHJhaW49cmVhZC5jc3YoIi4vaW5wdXRzL3RyYWluLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpDQp0ZXN0PXJlYWQuY3N2KCIuL2lucHV0cy90ZXN0LmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpDQoNCiNjaGVjayByZWFkIGluIGZpbGVzDQpwcmludCh0cmFpbikNCnByaW50KHRlc3QpDQpgYGANCg0KYGBge3J9DQojcmVtb3ZlIGlkIGZyb20gYm90aCB0cmFpbiBhbmQgdGVzdCB2YXJpYWJsZXMNCnRyYWluPXRyYWluWywtMV0NCnByaW50KHRyYWluKQ0KdGVzdD10ZXN0WywtMV0NCnByaW50KHRlc3QpDQpgYGANCg0KYGBge3J9DQojY29tYmluZSB0cmFpbiBhbmQgdGVzdCBzZXRzIGZvciBhbmFseXNpcyBhbmQgY2xlYW5pbmcNCiN0ZXN0IHNldCBoYXMgbWlzc2luZyBzYWxlcHJpY2UgKHVuZXFhbCBkaW1lbnNpb24gZm9yIG1lcmdpbmcgd2l0aCB0cmFpbiBzZXQpDQojbWFrZSBhIGNvcHkgb2YgdGhlIHRlc3Qgc2V0IGJlZm9yZSBhZGRpbmcgdGhlIGV4dHJhIGNvbHVtbg0KdGVzdF90bXA9dGVzdA0KdGVzdF90bXAkU2FsZVByaWNlPSBOQQ0KcHJpbnQodGVzdF90bXApDQoNCiNjb21iaW5lIHRoZSBhZGRlZC1jb2x1bW4gdGVzdCBzZXQgd2l0aCB0aGUgdHJhaW4gc2V0DQphbGw9cmJpbmQodHJhaW4sdGVzdF90bXApDQpwcmludChhbGwpDQpgYGANCmBgYHtyfQ0KI2ZpbmRpbmcgdGhlIG51bWJlciBvZiBudW1lcmljIGNvZGVzDQpudW1lcmljVmFycz13aGljaChzYXBwbHkoYWxsLCBpcy5udW1lcmljKSkNCm51bWVyaWNWYXJOYW1lcz1uYW1lcyhudW1lcmljVmFycykNCnNwcmludGYoIlRoZXJlIGFyZSAlcyBudW1lcmljIHZhcmlhYmxlcyIsIGxlbmd0aChudW1lcmljVmFycykpDQpgYGANCg0KDQoNCiAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgVGFidWxhdGUgdGhlIG51bWJlciBvZiBtaXNzaW5nIHZhbHVlcyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCg0KYGBge3J9DQojdGFidWxhdGUgdGhlIG51bWJlciBvZiBtaXNzaW5nIHZhbHVlcw0KbWlzc19mcmVxPXNvcnQoY29sU3Vtcyhpcy5uYShhbGwpKSxkZWNyZWFzaW5nPVRSVUUpDQpwcmludChtaXNzX2ZyZXEpDQpzcHJpbnRmKCJUaGVyZSBhcmUgJXMgY29sdW1ucyBvZiBtaXNzaW5nIHZhbHVlcyIsIHN1bShtaXNzX2ZyZXE+MCkpDQpgYGANCg0KDQogICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgVG8gZml4IGFsbCAzNCB2YXJpYWJsZXMgd2l0aCBtaXNzaW5nIHZhbHVlcyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KDQoxLiBQb29sUUM6IFBvb2wgcXVhbGl0eQ0KCQkNCiAgICAgICBFeAlFeGNlbGxlbnQNCiAgICAgICBHZAlHb29kDQogICAgICAgVEEJQXZlcmFnZS9UeXBpY2FsDQogICAgICAgRmEJRmFpcg0KICAgICAgIE5BCU5vIFBvb2wNCg0KYGBge3J9DQojcmVwbGFjZSBtaXNzaW5nIHZhbHVlcyBpbiBQb29sUUMNCiNBY2NvcmRpbmcgdG8gdGhlIGRhdGEgZGVzY3JpcHRpb24sIFBvb2xRQyBoYXMgRXhjZWxsZW50LCBHb29kLCBBdmVyYWdlLCBGYWlyIGFuZCBObyBQb29sIGxldmVscy4gTkEgcmVwcmVzZW50cyBObyBQb29sLg0KYWxsJFBvb2xRQ1tpcy5uYShhbGwkUG9vbFFDKV09J05vIFBvb2wnDQojY29udmVydCB0aGUgdmFyaWFibGUgdG8gb3JkaW5hbCBjbGFzcw0KdmFsdWVzPWMoIk5vIFBvb2wiPTAsIlBvIj0xLCJGYSI9MiwiVEEiPTMsIkdkIj00LCJFeCI9NSkNCmFsbCRQb29sUUM9YXMuaW50ZWdlcihyZXZhbHVlKGFsbCRQb29sUUMsdmFsdWVzKSkNCmNsYXNzKGFsbCRQb29sUUMpDQpgYGANCg0KYGBge3J9DQojYXNzZXNzaW5nIFBvb2xRQyB3aXRoIFBvb2xBcmVhDQphbGxbYWxsJFBvb2xRQz09MCAmIGFsbCRQb29sQXJlYT4wLCBjKCJQb29sUUMiLCJQb29sQXJlYSIsIk92ZXJhbGxRdWFsIildDQpgYGANCg0KYGBge3J9DQojdGhpcyBpbmRpY2F0ZXMgc29tZSBlcnJvciBpbiBmaWxsaW5nIHVwIG9mIHRoZSBtaXNzaW5nIHZhbHVlcy4gJzAnIGluZGljYXRlcyBubyBwb29sIHlldCBhbm90aGVyIHZhcmlhYmxlIHNob3dpbmcgaXRzIHBvb2wgYXJlYS4NCiNoZXJlIHdlIGFzc3VtZSBwb29scyBleGlzdCBmb3IgdGhlc2UgaG91c2VzIGJ1dCB3aXRob3V0IHF1YWxpdHkgcmF0aW5ncy4NCiN3ZSB3aWxsIHJlcGxhY2UgdGhlc2UgdmFsdWVzIHdpdGggcmVmZXJlbmNlIHRvICJPdmVyYWxsUXVhbCIgdmFyaWFibGUNCiN0aGVyZSBhcmUgMTAgb3JkaW5hbCBjYXRlZ29yaWVzIGluICJPdmVyYWxsUXVhbCIgYW5kIHdlIHJlc2FtcGxlZCBpdCBpbnRvIDUgY2F0ZWdvcmllcyB0byBtYXRjaCB3aXRoIFBvb2xRQyByYW5nZS4NCg0KYWxsWzI0MjEsIlBvb2xRQyJdPTINCmFsbFsyNTA0LCJQb29sUUMiXT0zDQphbGxbMjYwMCwiUG9vbFFDIl09Mg0KYGBgDQoNCjIuIE1pc2NGZWF0dXJlOiBNaXNjZWxsYW5lb3VzIGZlYXR1cmUgbm90IGNvdmVyZWQgaW4gb3RoZXIgY2F0ZWdvcmllcw0KCQkNCiAgICAgICBFbGV2CUVsZXZhdG9yDQogICAgICAgR2FyMgkybmQgR2FyYWdlIChpZiBub3QgZGVzY3JpYmVkIGluIGdhcmFnZSBzZWN0aW9uKQ0KICAgICAgIE90aHIJT3RoZXINCiAgICAgICBTaGVkCVNoZWQgKG92ZXIgMTAwIFNGKQ0KICAgICAgIFRlbkMJVGVubmlzIENvdXJ0DQogICAgICAgTkEJTm9uZQ0KDQpgYGB7cn0NCiNSZXBsYWNlIG1pc3NpbmcgdmFsdWVzIGluIE1pc2NGZWF0dXJlDQojTWlzY0ZlYXR1cmUgYWNjb3VudCBmb3IgdGhlIGFkZGl0aW9uYWwgZmFjaWxpdGllcyB0aGF0IGEgaG91c2UgbWlnaHQgcG9zc2Vzcywgc3VjaCBhcyBlbGV2YXRvciwgMm5kIEdhcmFyZ2UsIFNoZWQsIFRlbm5pcyBDb3VydCBhbmQgT3RoZXJzLg0KI1RoZSBOQXMgYXJlIGR1ZSB0byB0aGUgaG91c2UgaGF2aW5nIG5vIG90aGVyIGFkZGl0aW9uYWwgZmFjaWxpdGllcw0KI3JlcGxhY2luZyAnTkEnIHdpdGggJ05vbmUnIGFuZCB0aGlzIGZlYXR1cmUgc2hvdWxkIGJlaW4gZmFjdG9yIGZvcm0uDQphbGwkTWlzY0ZlYXR1cmVbaXMubmEoYWxsJE1pc2NGZWF0dXJlKV09J05vbmUnDQojY29udmVydCB0aGUgdmFyaWFibGUgdG8gZmFjdG9yIGNsYXNzDQphbGwkTWlzY0ZlYXR1cmU9YXMuZmFjdG9yKGFsbCRNaXNjRmVhdHVyZSkNCmNsYXNzKGFsbCRNaXNjRmVhdHVyZSkNCmBgYA0KDQozLiBBbGxleTogVHlwZSBvZiBhbGxleSBhY2Nlc3MgdG8gcHJvcGVydHkNCg0KICAgICAgIEdydmwJR3JhdmVsDQogICAgICAgUGF2ZQlQYXZlZA0KICAgICAgIE5BIAlObyBhbGxleSBhY2Nlc3MNCg0KYGBge3J9DQojTkEgcmVwcmVzZW50IG5vIGFsbGV5IGFjY2Vzcw0KYWxsJEFsbGV5W2lzLm5hKGFsbCRBbGxleSldPSdObyBhbGxleSBhY2Nlc3MnDQojY29udmVydCB0aGUgdmFyaWFibGUgdG8gZmFjdG9yIGNsYXNzDQphbGwkQWxsZXk9YXMuZmFjdG9yKGFsbCRBbGxleSkNCmNsYXNzKGFsbCRBbGxleSkNCmBgYA0KDQo0LiBGZW5jZTogRmVuY2UgcXVhbGl0eQ0KCQkNCiAgICAgICBHZFBydglHb29kIFByaXZhY3kNCiAgICAgICBNblBydglNaW5pbXVtIFByaXZhY3kNCiAgICAgICBHZFdvCUdvb2QgV29vZA0KICAgICAgIE1uV3cJTWluaW11bSBXb29kL1dpcmUNCiAgICAgICBOQQlObyBGZW5jZQ0KDQpgYGB7cn0NCiNOQSByZXByZXNlbnRzIE5vIEZlbmNlDQphbGwkRmVuY2VbaXMubmEoYWxsJEZlbmNlKV09J05vIEZlbmNlJw0KI2NvbnZlcnRpbmcgdGhpcyB0byBmYWN0b3IgY2xhc3MNCmFsbCRGZW5jZT1hcy5mYWN0b3IoYWxsJEZlbmNlKQ0KY2xhc3MoYWxsJEZlbmNlKQ0KYGBgDQoNCjUuIEZpcmVwbGFjZVF1OiBGaXJlcGxhY2UgcXVhbGl0eQ0KDQogICAgICAgRXgJRXhjZWxsZW50IC0gRXhjZXB0aW9uYWwgTWFzb25yeSBGaXJlcGxhY2UNCiAgICAgICBHZAlHb29kIC0gTWFzb25yeSBGaXJlcGxhY2UgaW4gbWFpbiBsZXZlbA0KICAgICAgIFRBCUF2ZXJhZ2UgLSBQcmVmYWJyaWNhdGVkIEZpcmVwbGFjZSBpbiBtYWluIGxpdmluZyBhcmVhIG9yIE1hc29ucnkgRmlyZXBsYWNlIGluIGJhc2VtZW50DQogICAgICAgRmEJRmFpciAtIFByZWZhYnJpY2F0ZWQgRmlyZXBsYWNlIGluIGJhc2VtZW50DQogICAgICAgUG8JUG9vciAtIEJlbiBGcmFua2xpbiBTdG92ZQ0KICAgICAgIE5BCU5vIEZpcmVwbGFjZQ0KICAgICAgIA0KYGBge3J9DQojcmVwbGFjZSBOQSB3aXRoIG5vIEZpcmVwbGFjZQ0KYWxsJEZpcmVwbGFjZVF1W2lzLm5hKGFsbCRGaXJlcGxhY2VRdSldPSJObyBGaXJlcGxhY2UiDQoNCiNhbm90aGVyIHZhcmlhYmxlIHRoYXQgaXMgY2xvc2VseSByZWxhdGVkIHRvIEZpcmVwbGFjZVF1IGlzIEZpcmVwbGFjZXMNCiNhbmQgbGV0J3MgY2hlY2sgd2hldGhlciB0aGUgbnVtYmVyIG9mIGhvdXNlcyB3aXRoIG5vIGZpcmVwbGFjZSBpbiAiRmlyZXBsYWNlcyIgZXF1YXRlcyB3aXRoIHRoZSBjb3VudCBpbiAiRmlyZXBsYWNlUXUiDQpzcHJpbnRmKCJUaGUgbnVtYmVyIG9mIE5vIEZpcmVwbGFjZSBpbiB2YXJpYWJsZXMgRmlyZXBsYWNlUXUgYW5kIEZpcmVwbGFjZXMgYXJlIGVxdWFsOiAlcyIsc3VtKGFsbCRGaXJlcGxhY2VRdT09Ik5vIEZpcmVwbGFjZSIpID09IHN1bShhbGwkRmlyZXBsYWNlcz09MCkpDQoNCiNjb252ZXJ0IHRoZSB2YXJpYWJsZSB0byBvcmRpbmFsIGNsYXNzDQp2YWx1ZXM9YygiTm8gRmlyZXBsYWNlIj0wLCJQbyI9MSwiRmEiPTIsIlRBIj0zLCJHZCI9NCwiRXgiPTUpDQphbGwkRmlyZXBsYWNlUXU9YXMuaW50ZWdlcihyZXZhbHVlKGFsbCRGaXJlcGxhY2VRdSx2YWx1ZXMpKQ0KY2xhc3MoYWxsJEZpcmVwbGFjZVF1KQ0KYGBgDQoNCjYuIExvdEZyb250YWdlOiBMaW5lYXIgZmVldCBvZiBzdHJlZXQgY29ubmVjdGVkIHRvIHByb3BlcnR5DQoNCiAgIE5laWdoYm9yaG9vZDogUGh5c2ljYWwgbG9jYXRpb25zIHdpdGhpbiBBbWVzIGNpdHkgbGltaXRzDQoNCiAgICAgICBCbG1uZ3RuCUJsb29taW5ndG9uIEhlaWdodHMNCiAgICAgICBCbHVlc3RlCUJsdWVzdGVtDQogICAgICAgQnJEYWxlCUJyaWFyZGFsZQ0KICAgICAgIEJya1NpZGUJQnJvb2tzaWRlDQogICAgICAgQ2xlYXJDcglDbGVhciBDcmVlaw0KICAgICAgIENvbGxnQ3IJQ29sbGVnZSBDcmVlaw0KICAgICAgIENyYXdmb3IJQ3Jhd2ZvcmQNCiAgICAgICBFZHdhcmRzCUVkd2FyZHMNCiAgICAgICBHaWxiZXJ0CUdpbGJlcnQNCiAgICAgICBJRE9UUlIJSW93YSBET1QgYW5kIFJhaWwgUm9hZA0KICAgICAgIE1lYWRvd1YJTWVhZG93IFZpbGxhZ2UNCiAgICAgICBNaXRjaGVsCU1pdGNoZWxsDQogICAgICAgTmFtZXMJTm9ydGggQW1lcw0KICAgICAgIE5vUmlkZ2UJTm9ydGhyaWRnZQ0KICAgICAgIE5Qa1ZpbGwJTm9ydGhwYXJrIFZpbGxhDQogICAgICAgTnJpZGdIdAlOb3J0aHJpZGdlIEhlaWdodHMNCiAgICAgICBOV0FtZXMJTm9ydGh3ZXN0IEFtZXMNCiAgICAgICBPbGRUb3duCU9sZCBUb3duDQogICAgICAgU1dJU1UJU291dGggJiBXZXN0IG9mIElvd2EgU3RhdGUgVW5pdmVyc2l0eQ0KICAgICAgIFNhd3llcglTYXd5ZXINCiAgICAgICBTYXd5ZXJXCVNhd3llciBXZXN0DQogICAgICAgU29tZXJzdAlTb21lcnNldA0KICAgICAgIFN0b25lQnIJU3RvbmUgQnJvb2sNCiAgICAgICBUaW1iZXIJVGltYmVybGFuZA0KICAgICAgIFZlZW5rZXIJVmVlbmtlcg0KDQpgYGB7cn0NCiNnZXQgdGhlIGluZGV4IGZvciB0aGUgcm93cyB3aXRoIG1pc3NpbmcgdmFsdWVzDQpMb3RfTkFzPWFsbFtpcy5uYShhbGwkTG90RnJvbnRhZ2UpLGMoIk5laWdoYm9yaG9vZCIsIkxvdEZyb250YWdlIildDQpwcmludChMb3RfTkFzKQ0KaWR4PWFzLm51bWVyaWMocm93bmFtZXMoTG90X05BcykpDQpwcmludChjbGFzcyhpZHgpKQ0KcHJpbnQobGVuZ3RoKGlkeCkpDQoNCiMgI3dlIHdpbGwgdXNlIHRoZSBtZWFuIGRpc3RhbmNlIG9mIGVhY2ggIk5laWdoYm91cmhvb2QiIHRvIHJlcGxhY2UgdGhlIG1pc3NpbmcgdmFsdWVzIGluICJMb3RGcm9udGFnZSINCmZvciAoaSBpbiBpZHgpew0KICAgICAgaWYoaXMubmEoYWxsJExvdEZyb250YWdlW2ldKSl7DQogICAgICAgICAgICAgIGFsbFtpLCJMb3RGcm9udGFnZSJdPWFzLmludGVnZXIobWVhbihhbGwkTG90RnJvbnRhZ2VbYWxsJE5laWdoYm9yaG9vZD09YWxsW2ksIk5laWdoYm9yaG9vZCJdXSwgbmEucm09VFJVRSkpDQogICAgICAgIH0NCn0NCnByaW50KGFsbFtjKDgsMTMsMTUsMTcpLCJMb3RGcm9udGFnZSJdKQ0KcHJpbnQoY2xhc3MoYWxsJExvdEZyb250YWdlKSkNCmBgYA0KDQo3LiBHYXJhZ2VZckJsdDogWWVhciBnYXJhZ2Ugd2FzIGJ1aWx0DQoNCmBgYHtyfQ0KI2Fzc29jaWF0ZSBob3VzZXMgd2l0aCBtaXNzaW5nIHZhbHVlcyBpbiB0aGlzIGNvbHVtbiBhcyBob3VzZXMgdGhhdCBkaWQgbm90IHJlYnVpbGQgb3IgcmVtb2RlbCBpdHMgZ2FyYWdlLg0KI3JlcGxhY2UgdGhpcyBtaXNzaW5nIHZhbHVlcyB3aXRoIHRoZSB5ZWFyIHRoZSBob3VzZSBpcyBidWlsdC4NCmFsbFtpcy5uYShhbGwkR2FyYWdlWXJCbHQpLCJHYXJhZ2VZckJsdCJdPWFsbCRZZWFyQnVpbHRbaXMubmEoYWxsJEdhcmFnZVlyQmx0KV0NCmNsYXNzKGFsbCRHYXJhZ2VZckJsdCkNCg0KI2NoZWNrIHdoZXRoZXIgdGhlIHZhbHVlcyBoYXZlIGJlZW4gcmVwbGFjZWQNCnN1bShpcy5uYShhbGwkR2FyYWdlWXJCbHQpKQ0KYGBgDQpQdXR0aW5nIGFsbCB2YXJpYWJsZXMgcmVsYXRlZCB0byBnYXJhZ2UgdG9nZXRoZXI6DQoNCk51bWJlciBvZiBtaXNzaW5nIHZhbHVlcyBpbiBnYXJhZy1yZWxhdGVkIGNvbXBvbmVudHM6DQoNCkdhcmFnZUZpbmlzaDogSW50ZXJpb3IgZmluaXNoIG9mIHRoZSBnYXJhZ2UgPSAxNTkNCkdhcmFnZVF1YWw6IEdhcmFnZSBxdWFsaXR5ID0gMTU5DQpHYXJhZ2VDb25kOiBHYXJhZ2UgY29uZGl0aW9uID0gMTU5DQpHYXJhZ2VUeXBlOiBHYXJhZ2UgbG9jYXRpb24gPSAxNTcNCkdhcmFnZUNhcnM6IFNpemUgb2YgZ2FyYWdlIGluIGNhciBjYXBhY2l0eSA9IDENCkdhcmFnZUFyZWE6IFNpemUgb2YgZ2FyYWdlIGluIHNxdWFyZSBmZWV0ID0gMQ0KDQoNCmBgYHtyfQ0KI0dhcmFnZUZpbmlzaCwgR2FyYWdlUXVhbCwgR2FyYWdlQ29uZCwgR2FyYWdlVHlwZSwgR2FyYWdlQ2FycyBhbmQgR2FyYWdlQXJlYSBzZWVtcyB0byBiZSBpbnRlci1yZWxhdGVkLg0KdG1wPWFsbFtpcy5uYShhbGwkR2FyYWdlRmluaXNoKSAmIGlzLm5hKGFsbCRHYXJhZ2VRdWFsKSAmIGlzLm5hKGFsbCRHYXJhZ2VDb25kKSAmIGlzLm5hKGFsbCRHYXJhZ2VUeXBlKSxdDQpzcHJpbnRmKCJob3cgbWFueSBvZiB0aGVzZSByb3dzIGhhdmUgTkEgdmFsdWVzIGluIEdhcmFnZUZpbmlzaCwgUXVhbCwgQ29uZCwgYW5kIFR5cGU6ICVzIiwgZGltKHRtcClbMV0pDQpgYGANCg0KYGBge3J9DQojdGhlIGFib3ZlIHJlc3VsdCBpbmRpY2F0ZXMgdGhlIHRoZSAxNTcgbWlzc2luZyB2YWx1ZXMgZm91bmQgaW4gR2FyYWdlVHlwZSBpcyBhbHNvIGZvdW5kIGluIEdhcmFnZUZpbmlzaCwgUXVhbGEgYW5kIENvbmQNCiMNCmFsbFtpcy5uYShhbGwkR2FyYWdlRmluaXNoKSAmIGlzLm5hKGFsbCRHYXJhZ2VRdWFsKSAmIGlzLm5hKGFsbCRHYXJhZ2VDb25kKSAmICFpcy5uYShhbGwkR2FyYWdlVHlwZSksIGMoIkdhcmFnZUZpbmlzaCIsIkdhcmFnZVF1YWwiLCJHYXJhZ2VDb25kIiwiR2FyYWdlVHlwZSIsIkdhcmFnZUNhcnMiLCJHYXJhZ2VBcmVhIildDQoNCiNhbGxbaXMubmEoYWxsJEdhcmFnZUNhcnMpIHwgaXMubmEoYWxsJEdhcmFnZUFyZWEpLCBjKCJHYXJhZ2VGaW5pc2giLCJHYXJhZ2VRdWFsIiwiR2FyYWdlQ29uZCIsIkdhcmFnZVR5cGUiLCJHYXJhZ2VDYXJzIiwiR2FyYWdlQXJlYSIpXQ0KYGBgDQoNCjguIEdhcmFnZUNhcnM6IFNpemUgb2YgZ2FyYWdlIGluIGNhciBjYXBhY2l0eSANCjkuIEdhcmFnZUFyZWE6IFNpemUgb2YgZ2FyYWdlIGluIHNxdWFyZSBmZWV0IA0KDQpgYGB7cn0NCiMgdGhlIHJlY29yZCAyMTI3IHNlZW1zIHRvIGhhdmUgYSBnYXJhZ2UgYXMgaXQgaGFzIHZhbHVlIGZvciBHYXJhZ2VDYXJzIGFuZCBHYXJhZ2VBcmVhDQojIG9uIHRoZSBvdGhlciBoYW5kLCAyNTc3IGRvZXMgbm90IHNlZW0gdG8gaGF2ZSBhIGdhcmFnZQ0KIyBsZXRzIGZpeCB0aGVzZSB0d28gZW50cmllcyBmaXJzdA0KDQojIGZ1bmN0aW9uOiBmaW5kaW5nIG1vZGUNCmdldG1vZGUgPC0gZnVuY3Rpb24odikgew0KICAgdW5pcXYgPC0gdW5pcXVlKHYpDQogICB1bmlxdlt3aGljaC5tYXgodGFidWxhdGUobWF0Y2godiwgdW5pcXYpKSldDQp9DQoNCiMgZW50cnkgMjEyNw0KYWxsWzIxMjcsIkdhcmFnZUZpbmlzaCJdPWdldG1vZGUoYWxsJEdhcmFnZUZpbmlzaCkNCmFsbFsyMTI3LCJHYXJhZ2VRdWFsIl09Z2V0bW9kZShhbGwkR2FyYWdlUXVhbCkNCmFsbFsyMTI3LCJHYXJhZ2VDb25kIl09Z2V0bW9kZShhbGwkR2FyYWdlQ29uZCkNCg0KIyBlbnRyeSAyNTc3DQphbGxbMjU3NywiR2FyYWdlVHlwZSJdPU5BDQphbGxbMjU3NywiR2FyYWdlQ2FycyJdPTANCmFsbFsyNTc3LCJHYXJhZ2VBcmVhIl09MA0KDQojY2hlY2sgdGhlIHJlY3RpZmljYXRpb24NCnByaW50KGFsbFtjKDIxMjcsMjU3NyksYygiR2FyYWdlRmluaXNoIiwiR2FyYWdlUXVhbCIsIkdhcmFnZUNvbmQiLCJHYXJhZ2VUeXBlIiwiR2FyYWdlQ2FycyIsIkdhcmFnZUFyZWEiKV0pDQpgYGANCmBgYHtyfQ0KdG1wPWFsbFtpcy5uYShhbGwkR2FyYWdlRmluaXNoKSAmIGlzLm5hKGFsbCRHYXJhZ2VRdWFsKSAmIGlzLm5hKGFsbCRHYXJhZ2VDb25kKSAmIGlzLm5hKGFsbCRHYXJhZ2VUeXBlKSxdDQpzcHJpbnRmKCJob3cgbWFueSBvZiB0aGVzZSByb3dzIGhhdmUgTkEgdmFsdWVzIGluIEdhcmFnZUZpbmlzaCwgUXVhbCwgQ29uZCwgYW5kIFR5cGUgKGFmdGVyIHJlcGxhY2VtZW50KTogJXMiLCBkaW0odG1wKVsxXSkNCmBgYA0KMTAuIEdhcmFnZUZpbmlzaDogSW50ZXJpb3IgZmluaXNoIG9mIHRoZSBnYXJhZ2UNCg0KICAgICAgIEZpbglGaW5pc2hlZA0KICAgICAgIFJGbglSb3VnaCBGaW5pc2hlZAkNCiAgICAgICBVbmYJVW5maW5pc2hlZA0KICAgICAgIE5BCU5vIEdhcmFnZQ0KDQpgYGB7cn0NCiN0aGUgTkFzIGluZGljYXRlICJObyBHYXJhZ2UiDQojcmVwbGFjZSBOQXMgd2l0aCAiTm8gR2FyYWdlIg0KYWxsW2lzLm5hKGFsbCRHYXJhZ2VGaW5pc2gpLCJHYXJhZ2VGaW5pc2giXT0iTm8gR2FyYWdlIg0KDQojY2hlY2sgdGhlIG51bWJlciBvZiBOQXMgYWdhaW4NCnN1bShpcy5uYShhbGwkR2FyYWdlRmluaXNoKSkNCg0KIyBjb252ZXJ0IHRoaXMgdmFyaWFibGUgdG8gb3JkaW5hbA0KdmFsdWVzPWMoJ05vIEdhcmFnZSc9MCwgJ1VuZic9MSwgJ1JGbic9MiwgJ0Zpbic9MykNCmFsbCRHYXJhZ2VGaW5pc2g9YXMuaW50ZWdlcihyZXZhbHVlKGFsbCRHYXJhZ2VGaW5pc2gsIHZhbHVlcykpDQpjbGFzcyhhbGwkR2FyYWdlRmluaXNoKQ0KYGBgDQoxMS4gR2FyYWdlUXVhbDogR2FyYWdlIHF1YWxpdHkNCg0KICAgICAgIEV4CUV4Y2VsbGVudA0KICAgICAgIEdkCUdvb2QNCiAgICAgICBUQQlUeXBpY2FsL0F2ZXJhZ2UNCiAgICAgICBGYQlGYWlyDQogICAgICAgUG8JUG9vcg0KICAgICAgIE5BCU5vIEdhcmFnZQ0KDQpgYGB7cn0NCiN0aGUgTkFzIGluZGljYXRlICJObyBHYXJhZ2UiDQojcmVwbGFjZSBOQXMgd2l0aCAiTm8gR2FyYWdlIg0KYWxsW2lzLm5hKGFsbCRHYXJhZ2VRdWFsKSwiR2FyYWdlUXVhbCJdPSJObyBHYXJhZ2UiDQoNCiNjaGVjayB0aGUgbnVtYmVyIG9mIE5BcyBhZ2Fpbg0Kc3VtKGlzLm5hKGFsbCRHYXJhZ2VRdWFsKSkNCg0KI2NvbnZlcnQgdG8gb3JkaW5hbA0KdmFsdWVzPWMoIk5vIEdhcmFnZSI9MCwiUG8iPTEsIkZhIj0yLCJUQSI9MywiR2QiPTQsIkV4Ij01KQ0KYWxsJEdhcmFnZVF1YWw9YXMuaW50ZWdlcihyZXZhbHVlKGFsbCRHYXJhZ2VRdWFsLCB2YWx1ZXMpKQ0KY2xhc3MoYWxsJEdhcmFnZVF1YWwpDQpgYGANCjEyLiBHYXJhZ2VDb25kOiBHYXJhZ2UgY29uZGl0aW9uDQoNCiAgICAgICBFeAlFeGNlbGxlbnQNCiAgICAgICBHZAlHb29kDQogICAgICAgVEEJVHlwaWNhbC9BdmVyYWdlDQogICAgICAgRmEJRmFpcg0KICAgICAgIFBvCVBvb3INCiAgICAgICBOQQlObyBHYXJhZ2UNCg0KYGBge3J9DQojdGhlIE5BcyBpbmRpY2F0ZSAiTm8gR2FyYWdlIg0KI3JlcGxhY2UgTkFzIHdpdGggIk5vIEdhcmFnZSINCmFsbFtpcy5uYShhbGwkR2FyYWdlQ29uZCksIkdhcmFnZUNvbmQiXT0iTm8gR2FyYWdlIg0KDQojY29udmVydCB0byBvcmRpbmFsDQp2YWx1ZXM9YygiTm8gR2FyYWdlIj0wLCJQbyI9MSwiRmEiPTIsIlRBIj0zLCJHZCI9NCwiRXgiPTUpDQphbGwkR2FyYWdlQ29uZD1hcy5pbnRlZ2VyKHJldmFsdWUoYWxsJEdhcmFnZUNvbmQsIHZhbHVlcykpDQpjbGFzcyhhbGwkR2FyYWdlQ29uZCkNCmBgYA0KMTMuIEdhcmFnZVR5cGU6IEdhcmFnZSBsb2NhdGlvbg0KCQkNCiAgICAgICAyVHlwZXMJTW9yZSB0aGFuIG9uZSB0eXBlIG9mIGdhcmFnZQ0KICAgICAgIEF0dGNoZAlBdHRhY2hlZCB0byBob21lDQogICAgICAgQmFzbWVudAlCYXNlbWVudCBHYXJhZ2UNCiAgICAgICBCdWlsdEluCUJ1aWx0LUluIChHYXJhZ2UgcGFydCBvZiBob3VzZSAtIHR5cGljYWxseSBoYXMgcm9vbSBhYm92ZSBnYXJhZ2UpDQogICAgICAgQ2FyUG9ydAlDYXIgUG9ydA0KICAgICAgIERldGNoZAlEZXRhY2hlZCBmcm9tIGhvbWUNCiAgICAgICBOQQlObyBHYXJhZ2UNCg0KYGBge3J9DQojdGhlIE5BcyBpbmRpY2F0ZSAiTm8gR2FyYWdlIg0KI3JlcGxhY2UgTkFzIHdpdGggIk5vIEdhcmFnZSINCmFsbFtpcy5uYShhbGwkR2FyYWdlVHlwZSksIkdhcmFnZVR5cGUiXT0iTm8gR2FyYWdlIg0KDQojY29udmVydCB0byBmYWN0b3IgY2xhc3MNCmFsbCRHYXJhZ2VUeXBlPWFzLmZhY3RvcihhbGwkR2FyYWdlVHlwZSkNCmNsYXNzKGFsbCRHYXJhZ2VUeXBlKQ0KYGBgDQoNClB1dHRpbmcgYWxsIHZhcmlhYmxlcyByZWxhdGVkIHRvIGJhc2VtZW50IHRvZ2V0aGVyOg0KDQpOby4gb2YgbWlzc2luZyB2YWx1ZXMgaW4gZWFjaCB2YXJpYWJsZToNCg0KQnNtdENvbmQ6IEV2YWx1YXRlcyB0aGUgZ2VuZXJhbCBjb25kaXRpb24gb2YgdGhlIGJhc2VtZW50ID0gODINCkJzbXRFeHBvc3VyZTogUmVmZXJzIHRvIHdhbGtvdXQgb3IgZ2FyZGVuIGxldmVsIHdhbGxzID0gODIgIA0KQnNtdFF1YWw6IEV2YWx1YXRlcyB0aGUgaGVpZ2h0IG9mIHRoZSBiYXNlbWVudCA9IDgxDQpCc210RmluVHlwZTI6IFJhdGluZyBvZiBiYXNlbWVudCBmaW5pc2hlZCBhcmVhID0gODANCkJzbXRGaW5UeXBlMTogUmF0aW5nIG9mIGJhc2VtZW50IGZpbmlzaGVkIGFyZWEgPSA3OQ0KQnNtdEZ1bGxCYXRoOiBCYXNlbWVudCBmdWxsIGJhdGhyb29tcyA9IDINCkJzbXRIYWxmQmF0aDogQmFzZW1lbnQgaGFsZiBiYXRocm9vbXMgPSAyDQpCc210RmluU0YxOiBUeXBlIDEgZmluaXNoZWQgc3F1YXJlIGZlZXQgPSAxDQpCc210RmluU0YyOiBUeXBlIDIgZmluaXNoZWQgc3F1YXJlIGZlZXQgPSAxDQpCc210VW5mU0Y6IFVuZmluaXNoZWQgc3F1YXJlIGZlZXQgb2YgYmFzZW1lbnQgYXJlYSA9IDENClRvdGFsQnNtdFNGOiBUb3RhbCBzcXVhcmUgZmVldCBvZiBiYXNlbWVudCBhcmVhID0gMQ0KDQpgYGB7cn0NCiNjaGVjayB3aGV0aGVyIHRoZSA3OSByZWNvcmRzIHdpdGggbWlzc2luZyB2YWx1ZXMgaW4gQnNtdEZpblR5cGUxIGNvcnJlc3BvbmQgd2l0aCB0aG9zZSBpbiBCc210Q29uZCwgRXhwb3N1cmUsIFF1YWwgYW5kIEZpblR5cGUyDQp0bXA9YWxsW2lzLm5hKGFsbCRCc210RmluVHlwZTEpICYgaXMubmEoYWxsJEJzbXRDb25kKSAmIGlzLm5hKGFsbCRCc210RXhwb3N1cmUpICYgaXMubmEoYWxsJEJzbXRRdWFsKSAmIGlzLm5hKGFsbCRCc210RmluVHlwZTIpLF0NCnByaW50KHRtcCkNCnNwcmludGYoIlRoZXJlIGFyZSAlcyByb3dzIHdpdGggTkFzIGluIGJzbXRmaW50eXBlMSwgYnNtdGNvbmQsIGJzbXRleHBvc3VyZSwgYnNtdHF1YWwgYW5kIGJzbXRmaW50eXBlMiBjb25jdXJyZW50bHkgIixkaW0odG1wKVsxXSkNCg0KI2ZpbmRpbmcgdGhlIG90aGVyIHJlY29yZHMgd2l0aCBOQSBpbiB0aGUgYmFzZW1lbnQgdmFyaWFibGVzLg0KYWxsWyFpcy5uYShhbGwkQnNtdEZpblR5cGUxKSAmIChpcy5uYShhbGwkQnNtdENvbmQpfGlzLm5hKGFsbCRCc210RXhwb3N1cmUpfGlzLm5hKGFsbCRCc210UXVhbCl8aXMubmEoYWxsJEJzbXRGaW5UeXBlMikpLGMoIkJzbXRGaW5UeXBlMSIsIkJzbXRDb25kIiwiQnNtdEV4cG9zdXJlIiwiQnNtdFF1YWwiLCJCc210RmluVHlwZTIiKV0NCmBgYA0KDQpgYGB7cn0NCiNlYWNoIHJvdyBpcyBvYnNlcnZlZCB0byBoYXZlIGEgbWlzc2luZyB2YWx1ZSBvdXQgb2YgZml2ZSB2YXJpYWJsZXMNCiN3ZSB3aWxsIHJlcGxhY2UgdGhlc2UgTkFzIHdpdGggdGhlIG1vZGUuDQoNCmFsbFszMzMsIkJzbXRGaW5UeXBlMiJdPWdldG1vZGUoYWxsJEJzbXRGaW5UeXBlMikNCmFsbFs5NDksIkJzbXRFeHBvc3VyZSJdPWdldG1vZGUoYWxsJEJzbXRFeHBvc3VyZSkNCmFsbFsxNDg4LCJCc210RXhwb3N1cmUiXT1nZXRtb2RlKGFsbCRCc210RXhwb3N1cmUpDQphbGxbMjA0MSwiQnNtdENvbmQiXT1nZXRtb2RlKGFsbCRCc210Q29uZCkNCmFsbFsyMTg2LCJCc210Q29uZCJdPWdldG1vZGUoYWxsJEJzbXRDb25kKQ0KYWxsWzIyMTgsIkJzbXRRdWFsIl09Z2V0bW9kZShhbGwkQnNtdFF1YWwpDQphbGxbMjIxOSwiQnNtdFF1YWwiXT1nZXRtb2RlKGFsbCRCc210UXVhbCkNCmFsbFsyMzQ5LCJCc210RXhwb3N1cmUiXT1nZXRtb2RlKGFsbCRCc210RXhwb3N1cmUpDQphbGxbMjUyNSwiQnNtdENvbmQiXT1nZXRtb2RlKGFsbCRCc210Q29uZCkNCg0KYWxsW2MoMzMzLDk0OSwxNDg4LDIwNDEsMjE4NiwyMjE4LDIyMTksMjM0OSwyNTI1KSxjKCJCc210RmluVHlwZTEiLCJCc210Q29uZCIsIkJzbXRFeHBvc3VyZSIsIkJzbXRRdWFsIiwiQnNtdEZpblR5cGUyIildDQpgYGANCjE0LiBCc210Q29uZDogRXZhbHVhdGVzIHRoZSBnZW5lcmFsIGNvbmRpdGlvbiBvZiB0aGUgYmFzZW1lbnQNCg0KICAgICAgIEV4CUV4Y2VsbGVudA0KICAgICAgIEdkCUdvb2QNCiAgICAgICBUQQlUeXBpY2FsIC0gc2xpZ2h0IGRhbXBuZXNzIGFsbG93ZWQNCiAgICAgICBGYQlGYWlyIC0gZGFtcG5lc3Mgb3Igc29tZSBjcmFja2luZyBvciBzZXR0bGluZw0KICAgICAgIFBvCVBvb3IgLSBTZXZlcmUgY3JhY2tpbmcsIHNldHRsaW5nLCBvciB3ZXRuZXNzDQogICAgICAgTkEJTm8gQmFzZW1lbnQNCg0KYGBge3J9DQojdGhlIE5BcyBpbmRpY2F0ZSAiTm8gQmFzZW1lbnQiDQojcmVwbGFjZSBOQXMgd2l0aCAiTm8gQmFzZW1lbnQiDQphbGxbaXMubmEoYWxsJEJzbXRDb25kKSwiQnNtdENvbmQiXT0iTm8gQmFzZW1lbnQiDQoNCiNjb252ZXJ0IHRvIG9yZGluYWwNCnZhbHVlcz1jKCJObyBCYXNlbWVudCI9MCwiUG8iPTEsIkZhIj0yLCJUQSI9MywiR2QiPTQsIkV4Ij01KQ0KYWxsJEJzbXRDb25kPWFzLmludGVnZXIocmV2YWx1ZShhbGwkQnNtdENvbmQsIHZhbHVlcykpDQpjbGFzcyhhbGwkQnNtdENvbmQpDQpgYGANCjE1LiBCc210RXhwb3N1cmU6IFJlZmVycyB0byB3YWxrb3V0IG9yIGdhcmRlbiBsZXZlbCB3YWxscw0KDQogICAgICAgR2QJR29vZCBFeHBvc3VyZQ0KICAgICAgIEF2CUF2ZXJhZ2UgRXhwb3N1cmUgKHNwbGl0IGxldmVscyBvciBmb3llcnMgdHlwaWNhbGx5IHNjb3JlIGF2ZXJhZ2Ugb3IgYWJvdmUpCQ0KICAgICAgIE1uCU1pbWltdW0gRXhwb3N1cmUNCiAgICAgICBObwlObyBFeHBvc3VyZQ0KICAgICAgIE5BCU5vIEJhc2VtZW50DQpgYGB7cn0NCiN0aGUgTkFzIGluZGljYXRlICJObyBCYXNlbWVudCINCiNyZXBsYWNlIE5BcyB3aXRoICJObyBCYXNlbWVudCINCmFsbFtpcy5uYShhbGwkQnNtdEV4cG9zdXJlKSwiQnNtdEV4cG9zdXJlIl09Ik5vIEJhc2VtZW50Ig0KDQojY29udmVydCB0byBvcmRpbmFsDQp2YWx1ZXM9YygiTm8gQmFzZW1lbnQiPTAsIk5vIj0xLCJNbiI9MiwiQXYiPTMsIkdkIj00KQ0KYWxsJEJzbXRFeHBvc3VyZT1hcy5pbnRlZ2VyKHJldmFsdWUoYWxsJEJzbXRFeHBvc3VyZSwgdmFsdWVzKSkNCmNsYXNzKGFsbCRCc210RXhwb3N1cmUpDQpgYGANCjE2LiBCc210UXVhbDogRXZhbHVhdGVzIHRoZSBoZWlnaHQgb2YgdGhlIGJhc2VtZW50DQoNCiAgICAgICBFeAlFeGNlbGxlbnQgKDEwMCsgaW5jaGVzKQkNCiAgICAgICBHZAlHb29kICg5MC05OSBpbmNoZXMpDQogICAgICAgVEEJVHlwaWNhbCAoODAtODkgaW5jaGVzKQ0KICAgICAgIEZhCUZhaXIgKDcwLTc5IGluY2hlcykNCiAgICAgICBQbwlQb29yICg8NzAgaW5jaGVzDQogICAgICAgTkEJTm8gQmFzZW1lbnQNCiAgICAgICANCmBgYHtyfQ0KI3RoZSBOQXMgaW5kaWNhdGUgIk5vIEJhc2VtZW50Ig0KI3JlcGxhY2UgTkFzIHdpdGggIk5vIEJhc2VtZW50Ig0KYWxsW2lzLm5hKGFsbCRCc210UXVhbCksIkJzbXRRdWFsIl09Ik5vIEJhc2VtZW50Ig0KDQojY29udmVydCB0byBvcmRpbmFsDQp2YWx1ZXM9YygiTm8gQmFzZW1lbnQiPTAsIlBvIj0xLCJGYSI9MiwiVEEiPTMsIkdkIj00LCJFeCI9NSkNCmFsbCRCc210UXVhbD1hcy5pbnRlZ2VyKHJldmFsdWUoYWxsJEJzbXRRdWFsLCB2YWx1ZXMpKQ0KY2xhc3MoYWxsJEJzbXRRdWFsKQ0KYGBgDQoxNy4gQnNtdEZpblR5cGUyOiBSYXRpbmcgb2YgYmFzZW1lbnQgZmluaXNoZWQgYXJlYSAoaWYgbXVsdGlwbGUgdHlwZXMpDQoNCiAgICAgICBHTFEJR29vZCBMaXZpbmcgUXVhcnRlcnMNCiAgICAgICBBTFEJQXZlcmFnZSBMaXZpbmcgUXVhcnRlcnMNCiAgICAgICBCTFEJQmVsb3cgQXZlcmFnZSBMaXZpbmcgUXVhcnRlcnMJDQogICAgICAgUmVjCUF2ZXJhZ2UgUmVjIFJvb20NCiAgICAgICBMd1EJTG93IFF1YWxpdHkNCiAgICAgICBVbmYJVW5maW5zaGVkDQogICAgICAgTkEJTm8gQmFzZW1lbnQNCg0KYGBge3J9DQojdGhlIE5BcyBpbmRpY2F0ZSAiTm8gQmFzZW1lbnQiDQojcmVwbGFjZSBOQXMgd2l0aCAiTm8gQmFzZW1lbnQiDQphbGxbaXMubmEoYWxsJEJzbXRGaW5UeXBlMiksIkJzbXRGaW5UeXBlMiJdPSJObyBCYXNlbWVudCINCg0KI2NvbnZlcnQgdG8gb3JkaW5hbA0KdmFsdWVzPWMoIk5vIEJhc2VtZW50Ij0wLCJVbmYiPTEsIkx3USI9MiwiUmVjIj0zLCJCTFEiPTQsIkFMUSI9NSwiR0xRIj02KQ0KYWxsJEJzbXRGaW5UeXBlMj1hcy5pbnRlZ2VyKHJldmFsdWUoYWxsJEJzbXRGaW5UeXBlMiwgdmFsdWVzKSkNCmNsYXNzKGFsbCRCc210RmluVHlwZTIpDQpgYGANCjE4LiBCc210RmluVHlwMTogUmF0aW5nIG9mIGJhc2VtZW50IGZpbmlzaGVkIGFyZWENCg0KICAgICAgIEdMUQlHb29kIExpdmluZyBRdWFydGVycw0KICAgICAgIEFMUQlBdmVyYWdlIExpdmluZyBRdWFydGVycw0KICAgICAgIEJMUQlCZWxvdyBBdmVyYWdlIExpdmluZyBRdWFydGVycwkNCiAgICAgICBSZWMJQXZlcmFnZSBSZWMgUm9vbQ0KICAgICAgIEx3UQlMb3cgUXVhbGl0eQ0KICAgICAgIFVuZglVbmZpbnNoZWQNCiAgICAgICBOQQlObyBCYXNlbWVudA0KICAgICAgIA0KYGBge3J9DQojdGhlIE5BcyBpbmRpY2F0ZSAiTm8gQmFzZW1lbnQiDQojcmVwbGFjZSBOQXMgd2l0aCAiTm8gQmFzZW1lbnQiDQphbGxbaXMubmEoYWxsJEJzbXRGaW5UeXBlMSksIkJzbXRGaW5UeXBlMSJdPSJObyBCYXNlbWVudCINCg0KI2NvbnZlcnQgdG8gb3JkaW5hbA0KdmFsdWVzPWMoIk5vIEJhc2VtZW50Ij0wLCJVbmYiPTEsIkx3USI9MiwiUmVjIj0zLCJCTFEiPTQsIkFMUSI9NSwiR0xRIj02KQ0KYWxsJEJzbXRGaW5UeXBlMT1hcy5pbnRlZ2VyKHJldmFsdWUoYWxsJEJzbXRGaW5UeXBlMSwgdmFsdWVzKSkNCmNsYXNzKGFsbCRCc210RmluVHlwZTEpDQpgYGANCjE5LiBCc210RnVsbEJhdGg6IEJhc2VtZW50IGZ1bGwgYmF0aHJvb21zDQoNCmBgYHtyfQ0KI3JlcGxhY2UgTkFzIHdpdGggemVybw0KYWxsW2lzLm5hKGFsbCRCc210RnVsbEJhdGgpLCJCc210RnVsbEJhdGgiXT0wDQpoaXN0KGFsbCRCc210RnVsbEJhdGgsIG1haW49Ikhpc3RvZ3JhbSBvZiBCc210RnVsbEJhdGgiLCB4bGFiPSJudW1iZXIgb2YgZnVsbCBiYXRocm9vbXMgaW4gYmFzZW1lbnQiKQ0KYGBgDQoyMC4gQnNtdEhhbGZCYXRoOiBCYXNlbWVudCBoYWxmIGJhdGhyb29tcw0KDQpgYGB7cn0NCiNyZXBsYWNlIE5BcyB3aXRoIHplcm8NCmFsbFtpcy5uYShhbGwkQnNtdEhhbGZCYXRoKSwiQnNtdEhhbGZCYXRoIl09MA0KaGlzdChhbGwkQnNtdEhhbGZCYXRoLCBtYWluPSJIaXN0b2dyYW0gb2YgQnNtdEhhbGZCYXRoIiwgeGxhYj0ibnVtYmVyIG9mIGhhbGYgYmF0aHJvb21zIGluIGJhc2VtZW50IikNCmBgYA0KDQoyMS4gQnNtdEZpblNGMTogVHlwZSAxIGZpbmlzaGVkIHNxdWFyZSBmZWV0DQoyMi5Cc210RmluU0YyOiBUeXBlIDIgZmluaXNoZWQgc3F1YXJlIGZlZXQNCjIzLiBCc210VW5mU0Y6IFVuZmluaXNoZWQgc3F1YXJlIGZlZXQgb2YgYmFzZW1lbnQgYXJlYQ0KMjQuIFRvdGFsQnNtdFNGOiBUb3RhbCBzcXVhcmUgZmVldCBvZiBiYXNlbWVudCBhcmVhDQoNCmBgYHtyfQ0KI3JlcGxhY2UgTkFzIHdpdGggemVybw0KI3RoZXkgYXJlIGludGVnZXJzDQphbGxbaXMubmEoYWxsJEJzbXRGaW5TRjEpLCJCc210RmluU0YxIl09MA0KYWxsW2lzLm5hKGFsbCRCc210RmluU0YyKSwiQnNtdEZpblNGMiJdPTANCmFsbFtpcy5uYShhbGwkQnNtdFVuZlNGKSwiQnNtdFVuZlNGIl09MA0KYWxsW2lzLm5hKGFsbCRUb3RhbEJzbXRTRiksIlRvdGFsQnNtdFNGIl09MA0KYGBgDQoNClB1dHRpbmcgcmVsYXRlZCB2YXJpYWJsZXMsIE1hc1ZuclR5cGUgKDI0IG1pc3NpbmcgdmFsdWVzKSBhbmQgTWFzVm5yQXJlYSgyMyBtaXNzaW5nIHZhbHVlcyksIHRvIGFzc2Vzcy4NCg0KYGBge3J9DQojdGhlIG51bWJlciBvZiByZWNvcmRzIHdpdGggTWFzVm5yVHlwZSBiZWluZyBOQSBnaXZlbiBNYXNWbnJBcmVhIGlzIGFsc28gTkEuDQp0bXA9YWxsW2lzLm5hKGFsbCRNYXNWbnJUeXBlKSAmIGlzLm5hKGFsbCRNYXNWbnJBcmVhKSxdDQpzcHJpbnRmKCJUaGUgbnVtYmVyIG9mIHJlY29yZHMgd2l0aCB3aXRoIE1hc1ZuclR5cGUgYmVpbmcgTkEgZ2l2ZW4gTWFzVm5yQXJlYSBpcyBhbHNvIE5BOiAlcyIsIGRpbSh0bXApWzFdKQ0KDQojZmluZGluZyB0aGUgZXh0cmEgTkEgcmVjb3JkIG9mIE1hc1ZuclR5cGUNCmFsbFtpcy5uYShhbGwkTWFzVm5yVHlwZSkgJiAhaXMubmEoYWxsJE1hc1ZuckFyZWEpLCBjKCJNYXNWbnJUeXBlIiwiTWFzVm5yQXJlYSIpXQ0KDQojY29ycmVjdCBlbnRyeSAyNjExDQp0YWJsZShhbGwkTWFzVm5yVHlwZSkNCiMiQnJrRmFjZSIgaGFzIHRoZSBoaWdoZXN0IG1vZGUgYWZ0ZXIgIk5vbmUiDQphbGxbMjYxMSxjKCJNYXNWbnJUeXBlIildPSJCcmtGYWNlIg0KcHJpbnQoYWxsWzI2MTEsYygiTWFzVm5yVHlwZSIsIk1hc1ZuckFyZWEiKV0pDQoNCiNyZXBsYWNlIE5BcyB3aXRoIE5vbmUNCmFsbFtpcy5uYShhbGwkTWFzVm5yVHlwZSksIk1hc1ZuclR5cGUiXT0iTm9uZSINCmBgYA0KMjUuIE1hc1ZuclR5cGU6IE1hc29ucnkgdmVuZWVyIHR5cGUgDQoNCiAgICAgICBCcmtDbW4JQnJpY2sgQ29tbW9uDQogICAgICAgQnJrRmFjZQlCcmljayBGYWNlDQogICAgICAgQ0Jsb2NrCUNpbmRlciBCbG9jaw0KICAgICAgIE5vbmUJTm9uZQ0KICAgICAgIFN0b25lCVN0b25lDQoNCmBgYHtyfQ0KI2NoZWNrIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgZGlmZmVyZW50IGNhdGVnb3J5IGluIE1hc1ZuclR5cGUgYW5kIFNhbGVQcmljZQ0KYXR0YWNoKGFsbCkNCmFnZ3JlZ2F0ZShhbGxbLGMoIk1hc1ZuclR5cGUiLCJTYWxlUHJpY2UiKV0sYnk9bGlzdChNYXNWbnJUeXBlKSxGVU49bWVhbixuYS5ybT1UUlVFKQ0KI3JlbGF0aW9uc2hpcCBzZWVtcyB0byBleGlzdCBiZXR3ZWVuICJNYXNWbnJUeXBlIiBhbmQgIlNhbGVQcmljZSINCiNjb252ZXJ0IHRvIG9yZGluYWwNCnZhbHVlcz1jKCJCcmtDbW4iPTAsIk5vbmUiPTEsIkJya0ZhY2UiPTIsIlN0b25lIj0zKQ0KYWxsJE1hc1ZuclR5cGU9YXMuaW50ZWdlcihyZXZhbHVlKGFsbCRNYXNWbnJUeXBlLCB2YWx1ZXMpKQ0KY2xhc3MoYWxsJE1hc1ZuclR5cGUpDQpgYGANCjI2LiBNYXNWbnJBcmVhOiBNYXNvbnJ5IHZlbmVlciBhcmVhIGluIHNxdWFyZSBmZWV0DQoNCmBgYHtyfQ0KI3JlcGxhY2UgTkFzIHdpdGggemVybw0KYWxsW2lzLm5hKGFsbCRNYXNWbnJBcmVhKSwiTWFzVm5yQXJlYSJdPTANCmBgYA0KMjcuIE1TWm9uaW5nOiBJZGVudGlmaWVzIHRoZSBnZW5lcmFsIHpvbmluZyBjbGFzc2lmaWNhdGlvbiBvZiB0aGUgc2FsZS4NCgkJDQogICAgICAgQQlBZ3JpY3VsdHVyZQ0KICAgICAgIEMJQ29tbWVyY2lhbA0KICAgICAgIEZWCUZsb2F0aW5nIFZpbGxhZ2UgUmVzaWRlbnRpYWwNCiAgICAgICBJCUluZHVzdHJpYWwNCiAgICAgICBSSAlSZXNpZGVudGlhbCBIaWdoIERlbnNpdHkNCiAgICAgICBSTAlSZXNpZGVudGlhbCBMb3cgRGVuc2l0eQ0KICAgICAgIFJQCVJlc2lkZW50aWFsIExvdyBEZW5zaXR5IFBhcmsgDQogICAgICAgUk0JUmVzaWRlbnRpYWwgTWVkaXVtIERlbnNpdHkNCg0KYGBge3J9DQojaW5wdXQgbWlzc2luZyB2YWx1ZXMgd2l0aCBtb2RlIGFuZCBjb252ZXJ0IHRvIGZhY3Rvcg0KYWxsW2lzLm5hKGFsbCRNU1pvbmluZyksIk1TWm9uaW5nIl09Z2V0bW9kZShhbGwkTVNab25pbmcpDQphbGwkTVNab25pbmc9YXMuZmFjdG9yKGFsbCRNU1pvbmluZykNCmNsYXNzKGFsbCRNU1pvbmluZykNCmBgYA0KMjguIEtpdGNoZW5RdWFsOiBLaXRjaGVuIHF1YWxpdHkNCg0KICAgICAgIEV4CUV4Y2VsbGVudA0KICAgICAgIEdkCUdvb2QNCiAgICAgICBUQQlUeXBpY2FsL0F2ZXJhZ2UNCiAgICAgICBGYQlGYWlyDQogICAgICAgUG8JUG9vcg0KDQpgYGB7cn0NCiNyZXBsYWNlIG1pc3NpbmcgdmFsdWVzIHdpdGggdGhlIG1vZGUNCmFsbFtpcy5uYShhbGwkS2l0Y2hlblF1YWwpLCJLaXRjaGVuUXVhbCJdPWdldG1vZGUoYWxsJEtpdGNoZW5RdWFsKQ0Kc3ByaW50ZigibnVtYmVyIG9mIG1pc3NpbmcgdmFsdWVzIGluIEtpdGNoZW5RdWFsKGFmdGVyIHJlcGxhY2VtZW50KTolcyIsIHN1bShpcy5uYShhbGwkS2l0Y2hlblF1YWwpKSkNCiNjb252ZXJ0IHRvIG9yZGluYWwNCnZhbHVlcz1jKCJQbyI9MCwiRmEiPTEsIlRBIj0yLCJHZCI9MywiRXgiPTQpDQphbGwkS2l0Y2hlblF1YWw9YXMuaW50ZWdlcihyZXZhbHVlKGFsbCRLaXRjaGVuUXVhbCwgdmFsdWVzKSkNCmNsYXNzKGFsbCRLaXRjaGVuUXVhbCkNCmBgYA0KMjkuIFV0aWxpdGllczogVHlwZSBvZiB1dGlsaXRpZXMgYXZhaWxhYmxlDQoJCQ0KICAgICAgIEFsbFB1YglBbGwgcHVibGljIFV0aWxpdGllcyAoRSxHLFcsJiBTKQkNCiAgICAgICBOb1Nld3IJRWxlY3RyaWNpdHksIEdhcywgYW5kIFdhdGVyIChTZXB0aWMgVGFuaykNCiAgICAgICBOb1NlV2EJRWxlY3RyaWNpdHkgYW5kIEdhcyBPbmx5DQogICAgICAgRUxPCUVsZWN0cmljaXR5IG9ubHkJDQoNCmBgYHtyfQ0KI2NoZWNraW5nIHRoZSBmcmVxdWVuY3kgb2YgZWFjaCBsZXZlbA0KdGFibGUoYWxsJFV0aWxpdGllcykNCg0KI3RoZSB0YWJsZSBzaG93cyB0aGF0IG1vc3Qgb2YgdGhlIHJvd3MgYXJlIGNhdGVnb3Jpc2VkIGFzICJBbGxQdWIiDQojdGhpcyB2YXJpYWJsZSBoZW5jZSBzZXJ2ZSBsaXR0bGUgdmFsdWUgaW4gcHJlZGljdGluZyB0aGUgcmVzcG9uc2UgdmFyYWlhYmxlDQphbGwkVXRpbGl0aWVzPU5VTEwNCmBgYA0KMzAuIEZ1bmN0aW9uYWw6IEhvbWUgZnVuY3Rpb25hbGl0eSAoQXNzdW1lIHR5cGljYWwgdW5sZXNzIGRlZHVjdGlvbnMgYXJlIHdhcnJhbnRlZCkNCg0KICAgICAgIFR5cAlUeXBpY2FsIEZ1bmN0aW9uYWxpdHkNCiAgICAgICBNaW4xCU1pbm9yIERlZHVjdGlvbnMgMQ0KICAgICAgIE1pbjIJTWlub3IgRGVkdWN0aW9ucyAyDQogICAgICAgTW9kCU1vZGVyYXRlIERlZHVjdGlvbnMNCiAgICAgICBNYWoxCU1ham9yIERlZHVjdGlvbnMgMQ0KICAgICAgIE1hajIJTWFqb3IgRGVkdWN0aW9ucyAyDQogICAgICAgU2V2CVNldmVyZWx5IERhbWFnZWQNCiAgICAgICBTYWwJU2FsdmFnZSBvbmx5DQoNCmBgYHtyfQ0KI3JlcGxhY2UgdGhlIG1pc3NpbmcgdmFsdWUgd2l0aCB0aGUgbW9kZQ0KYWxsW2lzLm5hKGFsbCRGdW5jdGlvbmFsKSwiRnVuY3Rpb25hbCJdPWdldG1vZGUoYWxsJEZ1bmN0aW9uYWwpDQoNCiNjb252ZXJ0IHRvIG9yZGluYWwNCnZhbHVlcz1jKCJTYWwiPTAsIlNldiI9MSwiTWFqMiI9MiwiTWFqMSI9MywiTW9kIj00LCJNaW4yIj01LCJNaW4xIj02LCJUeXAiPTcpDQphbGwkRnVuY3Rpb25hbD1hcy5pbnRlZ2VyKHJldmFsdWUoYWxsJEZ1bmN0aW9uYWwsIHZhbHVlcykpDQpjbGFzcyhhbGwkRnVuY3Rpb25hbCkNCnRhYmxlKGFsbCRGdW5jdGlvbmFsKQ0KDQojY2hlY2tpbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgRnVuY3Rpb25hbA0KdGFibGUoYWxsJEZ1bmN0aW9uYWwpDQpgYGANCjMxLiBFeHRlcmlvcjFzdDogRXh0ZXJpb3IgY292ZXJpbmcgb24gaG91c2UNCg0KICAgICAgIEFzYlNobmcJQXNiZXN0b3MgU2hpbmdsZXMNCiAgICAgICBBc3BoU2huCUFzcGhhbHQgU2hpbmdsZXMNCiAgICAgICBCcmtDb21tCUJyaWNrIENvbW1vbg0KICAgICAgIEJya0ZhY2UJQnJpY2sgRmFjZQ0KICAgICAgIENCbG9jawlDaW5kZXIgQmxvY2sNCiAgICAgICBDZW1udEJkCUNlbWVudCBCb2FyZA0KICAgICAgIEhkQm9hcmQJSGFyZCBCb2FyZA0KICAgICAgIEltU3R1Y2MJSW1pdGF0aW9uIFN0dWNjbw0KICAgICAgIE1ldGFsU2QJTWV0YWwgU2lkaW5nDQogICAgICAgT3RoZXIJT3RoZXINCiAgICAgICBQbHl3b29kCVBseXdvb2QNCiAgICAgICBQcmVDYXN0CVByZUNhc3QJDQogICAgICAgU3RvbmUJU3RvbmUNCiAgICAgICBTdHVjY28JU3R1Y2NvDQogICAgICAgVmlueWxTZAlWaW55bCBTaWRpbmcNCiAgICAgICBXZCBTZG5nCVdvb2QgU2lkaW5nDQogICAgICAgV2RTaGluZwlXb29kIFNoaW5nbGVzDQoNCmBgYHtyfQ0KI3JlcGxhY2UgbWlzc2luZyB2YWx1ZXMgd2l0aCB0aGUgbW9kZQ0KYWxsW2lzLm5hKGFsbCRFeHRlcmlvcjFzdCksIkV4dGVyaW9yMXN0Il09Z2V0bW9kZShhbGwkRXh0ZXJpb3Ixc3QpDQoNCiNjb252ZXJ0IGFzIGZhY3Rvcg0KYWxsJEV4dGVyaW9yMXN0PSBhcy5mYWN0b3IoYWxsJEV4dGVyaW9yMXN0KQ0KY2xhc3MoYWxsJEV4dGVyaW9yMXN0KQ0KYGBgDQozMi4gRXh0ZXJpb3IybmQ6IEV4dGVyaW9yIGNvdmVyaW5nIG9uIGhvdXNlIChpZiBtb3JlIHRoYW4gb25lIG1hdGVyaWFsKQ0KDQogICAgICAgQXNiU2huZwlBc2Jlc3RvcyBTaGluZ2xlcw0KICAgICAgIEFzcGhTaG4JQXNwaGFsdCBTaGluZ2xlcw0KICAgICAgIEJya0NvbW0JQnJpY2sgQ29tbW9uDQogICAgICAgQnJrRmFjZQlCcmljayBGYWNlDQogICAgICAgQ0Jsb2NrCUNpbmRlciBCbG9jaw0KICAgICAgIENlbW50QmQJQ2VtZW50IEJvYXJkDQogICAgICAgSGRCb2FyZAlIYXJkIEJvYXJkDQogICAgICAgSW1TdHVjYwlJbWl0YXRpb24gU3R1Y2NvDQogICAgICAgTWV0YWxTZAlNZXRhbCBTaWRpbmcNCiAgICAgICBPdGhlcglPdGhlcg0KICAgICAgIFBseXdvb2QJUGx5d29vZA0KICAgICAgIFByZUNhc3QJUHJlQ2FzdA0KICAgICAgIFN0b25lCVN0b25lDQogICAgICAgU3R1Y2NvCVN0dWNjbw0KICAgICAgIFZpbnlsU2QJVmlueWwgU2lkaW5nDQogICAgICAgV2QgU2RuZwlXb29kIFNpZGluZw0KICAgICAgIFdkU2hpbmcJV29vZCBTaGluZ2xlcw0KDQpgYGB7cn0NCiNyZXBsYWNlIG1pc3NpbmcgdmFsdWVzIHdpdGggdGhlIG1vZGUNCmFsbFtpcy5uYShhbGwkRXh0ZXJpb3IybmQpLCJFeHRlcmlvcjJuZCJdPWdldG1vZGUoYWxsJEV4dGVyaW9yMm5kKQ0KDQojY29udmVydCBhcyBmYWN0b3INCmFsbCRFeHRlcmlvcjJuZD0gYXMuZmFjdG9yKGFsbCRFeHRlcmlvcjJuZCkNCmNsYXNzKGFsbCRFeHRlcmlvcjJuZCkNCmBgYA0KMzMuRWxlY3RyaWNhbDogRWxlY3RyaWNhbCBzeXN0ZW0NCg0KICAgICAgIFNCcmtyCVN0YW5kYXJkIENpcmN1aXQgQnJlYWtlcnMgJiBSb21leA0KICAgICAgIEZ1c2VBCUZ1c2UgQm94IG92ZXIgNjAgQU1QIGFuZCBhbGwgUm9tZXggd2lyaW5nIChBdmVyYWdlKQkNCiAgICAgICBGdXNlRgk2MCBBTVAgRnVzZSBCb3ggYW5kIG1vc3RseSBSb21leCB3aXJpbmcgKEZhaXIpDQogICAgICAgRnVzZVAJNjAgQU1QIEZ1c2UgQm94IGFuZCBtb3N0bHkga25vYiAmIHR1YmUgd2lyaW5nIChwb29yKQ0KICAgICAgIE1peAlNaXhlZA0KDQpgYGB7cn0NCiNyZXBsYWNlIG1pc3NpbmcgdmFsdWUgd2l0aCBtb2RlIGFuZCBjb252ZXJ0IHZhcmlhYmxlIHRvIGZhY3Rvcg0KYWxsW2lzLm5hKGFsbCRFbGVjdHJpY2FsKSwiRWxlY3RyaWNhbCJdPWdldG1vZGUoYWxsJEVsZWN0cmljYWwpDQoNCmFsbCRFbGVjdHJpY2FsPWFzLmZhY3RvcihhbGwkRWxlY3RyaWNhbCkNCmNsYXNzKGFsbCRFbGVjdHJpY2FsKQ0KdGFibGUoYWxsJEVsZWN0cmljYWwpDQpgYGANCjM0LiBTYWxlVHlwZTogVHlwZSBvZiBzYWxlDQoJCQ0KICAgICAgIFdEIAlXYXJyYW50eSBEZWVkIC0gQ29udmVudGlvbmFsDQogICAgICAgQ1dECVdhcnJhbnR5IERlZWQgLSBDYXNoDQogICAgICAgVldECVdhcnJhbnR5IERlZWQgLSBWQSBMb2FuDQogICAgICAgTmV3CUhvbWUganVzdCBjb25zdHJ1Y3RlZCBhbmQgc29sZA0KICAgICAgIENPRAlDb3VydCBPZmZpY2VyIERlZWQvRXN0YXRlDQogICAgICAgQ29uCUNvbnRyYWN0IDE1JSBEb3duIHBheW1lbnQgcmVndWxhciB0ZXJtcw0KICAgICAgIENvbkx3CUNvbnRyYWN0IExvdyBEb3duIHBheW1lbnQgYW5kIGxvdyBpbnRlcmVzdA0KICAgICAgIENvbkxJCUNvbnRyYWN0IExvdyBJbnRlcmVzdA0KICAgICAgIENvbkxECUNvbnRyYWN0IExvdyBEb3duDQogICAgICAgT3RoCU90aGVyDQoNCmBgYHtyfQ0KI3JlcGxhY2UgbWlzc2luZyB2YWx1ZSB3aXRoIG1vZGUgYW5kIGNvbnZlcnQgdmFyaWFibGUgdG8gZmFjdG9yDQphbGxbaXMubmEoYWxsJFNhbGVUeXBlKSwiU2FsZVR5cGUiXT1nZXRtb2RlKGFsbCRTYWxlVHlwZSkNCg0KYWxsJFNhbGVUeXBlPWFzLmZhY3RvcihhbGwkU2FsZVR5cGUpDQpjbGFzcyhhbGwkU2FsZVR5cGUpDQp0YWJsZShhbGwkU2FsZVR5cGUpDQpgYGANCg0KICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ29udmVydCB0aGUgcmVtYWluaW5nIHZhcmlhYmxlcyB0byBhcHByb3ByaWF0ZSBjbGFzcyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KDQphLiBGb3VuZGF0aW9uOiBUeXBlIG9mIGZvdW5kYXRpb24NCgkJDQogICAgICAgQnJrVGlsCUJyaWNrICYgVGlsZQ0KICAgICAgIENCbG9jawlDaW5kZXIgQmxvY2sNCiAgICAgICBQQ29uYwlQb3VyZWQgQ29udHJldGUJDQogICAgICAgU2xhYglTbGFiDQogICAgICAgU3RvbmUJU3RvbmUNCiAgICAgICBXb29kCVdvb2QNCg0KDQpgYGB7cn0NCiNjb252ZXJ0aW5nIGludG8gZmFjdG9yIGNsYXNzDQphbGwkRm91bmRhdGlvbj1hcy5mYWN0b3IoYWxsJEZvdW5kYXRpb24pDQpjbGFzcyhhbGwkRm91bmRhdGlvbikNCmBgYA0KYi4gSGVhdGluZzogVHlwZSBvZiBoZWF0aW5nDQoJCQ0KICAgICAgIEZsb29yCUZsb29yIEZ1cm5hY2UNCiAgICAgICBHYXNBCUdhcyBmb3JjZWQgd2FybSBhaXIgZnVybmFjZQ0KICAgICAgIEdhc1cJR2FzIGhvdCB3YXRlciBvciBzdGVhbSBoZWF0DQogICAgICAgR3JhdglHcmF2aXR5IGZ1cm5hY2UJDQogICAgICAgT3RoVwlIb3Qgd2F0ZXIgb3Igc3RlYW0gaGVhdCBvdGhlciB0aGFuIGdhcw0KICAgICAgIFdhbGwJV2FsbCBmdXJuYWNlDQoNCmBgYHtyfQ0KI2NvbnZlcnRpbmcgaW50byBmYWN0b3IgY2xhc3MNCmFsbCRIZWF0aW5nPWFzLmZhY3RvcihhbGwkSGVhdGluZykNCmNsYXNzKGFsbCRIZWF0aW5nKQ0KYGBgDQpjLiBIZWF0aW5nUUM6IEhlYXRpbmcgcXVhbGl0eSBhbmQgY29uZGl0aW9uDQoNCiAgICAgICBFeAlFeGNlbGxlbnQNCiAgICAgICBHZAlHb29kDQogICAgICAgVEEJQXZlcmFnZS9UeXBpY2FsDQogICAgICAgRmEJRmFpcg0KICAgICAgIFBvCVBvb3INCg0KYGBge3J9DQojY29udmVydGluZyBpbnRvIG9yZGluYWwNCnZhbHVlcz1jKCJQbyI9MCwiRmEiPTEsIlRBIj0yLCJHZCI9MywiRXgiPTQpDQphbGwkSGVhdGluZ1FDPWFzLmludGVnZXIocmV2YWx1ZShhbGwkSGVhdGluZ1FDLCB2YWx1ZXMpKQ0KY2xhc3MoYWxsJEhlYXRpbmdRQykNCmBgYA0KZC4gQ2VudHJhbEFpcjogQ2VudHJhbCBhaXIgY29uZGl0aW9uaW5nDQoNCiAgICAgICBOCU5vDQogICAgICAgWQlZZXMNCg0KYGBge3J9DQojY29udmVydCB0byBvcmRpbmFsDQp2YWx1ZXM9YygiTiI9MCwiWSI9MSkNCmFsbCRDZW50cmFsQWlyPWFzLmludGVnZXIocmV2YWx1ZShhbGwkQ2VudHJhbEFpciwgdmFsdWVzKSkNCmNsYXNzKGFsbCRDZW50cmFsQWlyKQ0KYGBgDQplLiBSb29mU3R5bGU6IFR5cGUgb2Ygcm9vZg0KDQogICAgICAgRmxhdAlGbGF0DQogICAgICAgR2FibGUJR2FibGUNCiAgICAgICBHYW1icmVsCUdhYnJlbCAoQmFybikNCiAgICAgICBIaXAJSGlwDQogICAgICAgTWFuc2FyZAlNYW5zYXJkDQogICAgICAgU2hlZAlTaGVkDQoNCmBgYHtyfQ0KI2NvbnZlcnRpbmcgaW50byBmYWN0b3IgY2xhc3MNCmFsbCRSb29mU3R5bGU9YXMuZmFjdG9yKGFsbCRSb29mU3R5bGUpDQpjbGFzcyhhbGwkUm9vZlN0eWxlKQ0KYGBgDQpmLlJvb2ZNYXRsOiBSb29mIG1hdGVyaWFsDQoNCiAgICAgICBDbHlUaWxlCUNsYXkgb3IgVGlsZQ0KICAgICAgIENvbXBTaGcJU3RhbmRhcmQgKENvbXBvc2l0ZSkgU2hpbmdsZQ0KICAgICAgIE1lbWJyYW4JTWVtYnJhbmUNCiAgICAgICBNZXRhbAlNZXRhbA0KICAgICAgIFJvbGwJUm9sbA0KICAgICAgIFRhciZHcnYJR3JhdmVsICYgVGFyDQogICAgICAgV2RTaGFrZQlXb29kIFNoYWtlcw0KICAgICAgIFdkU2huZ2wJV29vZCBTaGluZ2xlcw0KDQpgYGB7cn0NCiNjb252ZXJ0aW5nIGludG8gZmFjdG9yIGNsYXNzDQphbGwkUm9vZk1hdGw9YXMuZmFjdG9yKGFsbCRSb29mTWF0bCkNCmNsYXNzKGFsbCRSb29mTWF0bCkNCmBgYA0KZy4gTGFuZENvbnRvdXI6IEZsYXRuZXNzIG9mIHRoZSBwcm9wZXJ0eQ0KDQogICAgICAgTHZsCU5lYXIgRmxhdC9MZXZlbAkNCiAgICAgICBCbmsJQmFua2VkIC0gUXVpY2sgYW5kIHNpZ25pZmljYW50IHJpc2UgZnJvbSBzdHJlZXQgZ3JhZGUgdG8gYnVpbGRpbmcNCiAgICAgICBITFMJSGlsbHNpZGUgLSBTaWduaWZpY2FudCBzbG9wZSBmcm9tIHNpZGUgdG8gc2lkZQ0KICAgICAgIExvdwlEZXByZXNzaW9uDQoNCmBgYHtyfQ0KI2NvbnZlcnRpbmcgaW50byBmYWN0b3IgY2xhc3MNCmFsbCRMYW5kQ29udG91cj1hcy5mYWN0b3IoYWxsJExhbmRDb250b3VyKQ0KY2xhc3MoYWxsJExhbmRDb250b3VyKQ0KYGBgDQpoLkxhbmRTbG9wZTogU2xvcGUgb2YgcHJvcGVydHkNCgkJDQogICAgICAgR3RsCUdlbnRsZSBzbG9wZQ0KICAgICAgIE1vZAlNb2RlcmF0ZSBTbG9wZQkNCiAgICAgICBTZXYJU2V2ZXJlIFNsb3BlDQoNCmBgYHtyfQ0KI2NvbnZlcnRpbmcgdG8gb3JkaW5hbA0KdmFsdWVzPWMoIlNldiI9MCwiTW9kIj0xLCJHdGwiPTIpDQphbGwkTGFuZFNsb3BlPWFzLmludGVnZXIocmV2YWx1ZShhbGwkTGFuZFNsb3BlLCB2YWx1ZXMpKQ0KY2xhc3MoYWxsJExhbmRTbG9wZSkNCmBgYA0KaS4gQmxkZ1R5cGU6IFR5cGUgb2YgZHdlbGxpbmcNCgkJDQogICAgICAgMUZhbQlTaW5nbGUtZmFtaWx5IERldGFjaGVkCQ0KICAgICAgIDJGbUNvbglUd28tZmFtaWx5IENvbnZlcnNpb247IG9yaWdpbmFsbHkgYnVpbHQgYXMgb25lLWZhbWlseSBkd2VsbGluZw0KICAgICAgIER1cGx4CUR1cGxleA0KICAgICAgIFR3bmhzRQlUb3duaG91c2UgRW5kIFVuaXQNCiAgICAgICBUd25oc0kJVG93bmhvdXNlIEluc2lkZSBVbml0DQogICAgICAgDQpgYGB7cn0NCiNjb252ZXJ0IHRvIGZhY3Rvcg0KYWxsJEJsZGdUeXBlPWFzLmZhY3RvcihhbGwkQmxkZ1R5cGUpDQpjbGFzcyhhbGwkQmxkZ1R5cGUpDQpgYGANCmouIEhvdXNlU3R5bGU6IFN0eWxlIG9mIGR3ZWxsaW5nDQoJDQogICAgICAgMVN0b3J5CU9uZSBzdG9yeQ0KICAgICAgIDEuNUZpbglPbmUgYW5kIG9uZS1oYWxmIHN0b3J5OiAybmQgbGV2ZWwgZmluaXNoZWQNCiAgICAgICAxLjVVbmYJT25lIGFuZCBvbmUtaGFsZiBzdG9yeTogMm5kIGxldmVsIHVuZmluaXNoZWQNCiAgICAgICAyU3RvcnkJVHdvIHN0b3J5DQogICAgICAgMi41RmluCVR3byBhbmQgb25lLWhhbGYgc3Rvcnk6IDJuZCBsZXZlbCBmaW5pc2hlZA0KICAgICAgIDIuNVVuZglUd28gYW5kIG9uZS1oYWxmIHN0b3J5OiAybmQgbGV2ZWwgdW5maW5pc2hlZA0KICAgICAgIFNGb3llcglTcGxpdCBGb3llcg0KICAgICAgIFNMdmwJU3BsaXQgTGV2ZWwNCg0KYGBge3J9DQojY29udmVydCB0byBmYWN0b3INCmFsbCRIb3VzZVN0eWxlPWFzLmZhY3RvcihhbGwkSG91c2VTdHlsZSkNCmNsYXNzKGFsbCRIb3VzZVN0eWxlKQ0KYGBgDQprLiBOZWlnaGJvcmhvb2Q6IFBoeXNpY2FsIGxvY2F0aW9ucyB3aXRoaW4gQW1lcyBjaXR5IGxpbWl0cw0KDQogICAgICAgQmxtbmd0bglCbG9vbWluZ3RvbiBIZWlnaHRzDQogICAgICAgQmx1ZXN0ZQlCbHVlc3RlbQ0KICAgICAgIEJyRGFsZQlCcmlhcmRhbGUNCiAgICAgICBCcmtTaWRlCUJyb29rc2lkZQ0KICAgICAgIENsZWFyQ3IJQ2xlYXIgQ3JlZWsNCiAgICAgICBDb2xsZ0NyCUNvbGxlZ2UgQ3JlZWsNCiAgICAgICBDcmF3Zm9yCUNyYXdmb3JkDQogICAgICAgRWR3YXJkcwlFZHdhcmRzDQogICAgICAgR2lsYmVydAlHaWxiZXJ0DQogICAgICAgSURPVFJSCUlvd2EgRE9UIGFuZCBSYWlsIFJvYWQNCiAgICAgICBNZWFkb3dWCU1lYWRvdyBWaWxsYWdlDQogICAgICAgTWl0Y2hlbAlNaXRjaGVsbA0KICAgICAgIE5hbWVzCU5vcnRoIEFtZXMNCiAgICAgICBOb1JpZGdlCU5vcnRocmlkZ2UNCiAgICAgICBOUGtWaWxsCU5vcnRocGFyayBWaWxsYQ0KICAgICAgIE5yaWRnSHQJTm9ydGhyaWRnZSBIZWlnaHRzDQogICAgICAgTldBbWVzCU5vcnRod2VzdCBBbWVzDQogICAgICAgT2xkVG93bglPbGQgVG93bg0KICAgICAgIFNXSVNVCVNvdXRoICYgV2VzdCBvZiBJb3dhIFN0YXRlIFVuaXZlcnNpdHkNCiAgICAgICBTYXd5ZXIJU2F3eWVyDQogICAgICAgU2F3eWVyVwlTYXd5ZXIgV2VzdA0KICAgICAgIFNvbWVyc3QJU29tZXJzZXQNCiAgICAgICBTdG9uZUJyCVN0b25lIEJyb29rDQogICAgICAgVGltYmVyCVRpbWJlcmxhbmQNCiAgICAgICBWZWVua2VyCVZlZW5rZXINCg0KYGBge3J9DQojY29udmVydCB0byBmYWN0b3INCmFsbCROZWlnaGJvcmhvb2Q9YXMuZmFjdG9yKGFsbCROZWlnaGJvcmhvb2QpDQpjbGFzcyhhbGwkTmVpZ2hib3Job29kKQ0KYGBgDQpsLiBDb25kaXRpb24xOiBQcm94aW1pdHkgdG8gdmFyaW91cyBjb25kaXRpb25zDQoJDQogICAgICAgQXJ0ZXJ5CUFkamFjZW50IHRvIGFydGVyaWFsIHN0cmVldA0KICAgICAgIEZlZWRyCUFkamFjZW50IHRvIGZlZWRlciBzdHJlZXQJDQogICAgICAgTm9ybQlOb3JtYWwJDQogICAgICAgUlJObglXaXRoaW4gMjAwJyBvZiBOb3J0aC1Tb3V0aCBSYWlscm9hZA0KICAgICAgIFJSQW4JQWRqYWNlbnQgdG8gTm9ydGgtU291dGggUmFpbHJvYWQNCiAgICAgICBQb3NOCU5lYXIgcG9zaXRpdmUgb2ZmLXNpdGUgZmVhdHVyZS0tcGFyaywgZ3JlZW5iZWx0LCBldGMuDQogICAgICAgUG9zQQlBZGphY2VudCB0byBwb3N0aXZlIG9mZi1zaXRlIGZlYXR1cmUNCiAgICAgICBSUk5lCVdpdGhpbiAyMDAnIG9mIEVhc3QtV2VzdCBSYWlscm9hZA0KICAgICAgIFJSQWUJQWRqYWNlbnQgdG8gRWFzdC1XZXN0IFJhaWxyb2FkDQoNCmBgYHtyfQ0KI2NvbnZlcnQgdG8gZmFjdG9yDQphbGwkQ29uZGl0aW9uMT1hcy5mYWN0b3IoYWxsJENvbmRpdGlvbjEpDQpjbGFzcyhhbGwkQ29uZGl0aW9uMSkNCmBgYA0KbS4gQ29uZGl0aW9uMjogUHJveGltaXR5IHRvIHZhcmlvdXMgY29uZGl0aW9ucyAoaWYgbW9yZSB0aGFuIG9uZSBpcyBwcmVzZW50KQ0KCQkNCiAgICAgICBBcnRlcnkJQWRqYWNlbnQgdG8gYXJ0ZXJpYWwgc3RyZWV0DQogICAgICAgRmVlZHIJQWRqYWNlbnQgdG8gZmVlZGVyIHN0cmVldAkNCiAgICAgICBOb3JtCU5vcm1hbAkNCiAgICAgICBSUk5uCVdpdGhpbiAyMDAnIG9mIE5vcnRoLVNvdXRoIFJhaWxyb2FkDQogICAgICAgUlJBbglBZGphY2VudCB0byBOb3J0aC1Tb3V0aCBSYWlscm9hZA0KICAgICAgIFBvc04JTmVhciBwb3NpdGl2ZSBvZmYtc2l0ZSBmZWF0dXJlLS1wYXJrLCBncmVlbmJlbHQsIGV0Yy4NCiAgICAgICBQb3NBCUFkamFjZW50IHRvIHBvc3RpdmUgb2ZmLXNpdGUgZmVhdHVyZQ0KICAgICAgIFJSTmUJV2l0aGluIDIwMCcgb2YgRWFzdC1XZXN0IFJhaWxyb2FkDQogICAgICAgUlJBZQlBZGphY2VudCB0byBFYXN0LVdlc3QgUmFpbHJvYWQNCg0KYGBge3J9DQojY29udmVydCB0byBmYWN0b3INCmFsbCRDb25kaXRpb24yPWFzLmZhY3RvcihhbGwkQ29uZGl0aW9uMikNCmNsYXNzKGFsbCRDb25kaXRpb24yKQ0KYGBgDQpuLiBTdHJlZXQ6IFR5cGUgb2Ygcm9hZCBhY2Nlc3MgdG8gcHJvcGVydHkNCg0KICAgICAgIEdydmwJR3JhdmVsCQ0KICAgICAgIFBhdmUJUGF2ZWQNCiAgICAgICANCmBgYHtyfQ0KI2NvbnZlcnQgdG8gb3JkaW5hbA0KdmFsdWVzPWMoIkdydmwiPTAsIlBhdmUiPTEpDQphbGwkU3RyZWV0PWFzLmludGVnZXIocmV2YWx1ZShhbGwkU3RyZWV0LCB2YWx1ZXMpKQ0KY2xhc3MoYWxsJFN0cmVldCkNCmBgYA0Kby4gUGF2ZWREcml2ZTogUGF2ZWQgZHJpdmV3YXkNCg0KICAgICAgIFkJUGF2ZWQgDQogICAgICAgUAlQYXJ0aWFsIFBhdmVtZW50DQogICAgICAgTglEaXJ0L0dyYXZlbA0KICAgICAgIA0KYGBge3J9DQojY29udmVydCB0byBvcmRpbmFsDQp2YWx1ZXM9YygiTiI9MCwiUCI9MSwiWSI9MikNCmFsbCRQYXZlZERyaXZlPWFzLmludGVnZXIocmV2YWx1ZShhbGwkUGF2ZWREcml2ZSwgdmFsdWVzKSkNCmNsYXNzKGFsbCRQYXZlZERyaXZlKQ0KYGBgDQpwLiBFeHRlclF1YWw6IEV2YWx1YXRlcyB0aGUgcXVhbGl0eSBvZiB0aGUgbWF0ZXJpYWwgb24gdGhlIGV4dGVyaW9yIA0KCQkNCiAgICAgICBFeAlFeGNlbGxlbnQNCiAgICAgICBHZAlHb29kDQogICAgICAgVEEJQXZlcmFnZS9UeXBpY2FsDQogICAgICAgRmEJRmFpcg0KICAgICAgIFBvCVBvb3INCiAgICAgICANCmBgYHtyfQ0KI2NvbnZlcnQgdG8gb3JkaW5hbA0KdmFsdWVzPWMoIlBvIj0wLCJGYSI9MSwiVEEiPTIsIkdkIj0zLCJFeCI9NCkNCmFsbCRFeHRlclF1YWw9YXMuaW50ZWdlcihyZXZhbHVlKGFsbCRFeHRlclF1YWwsIHZhbHVlcykpDQpjbGFzcyhhbGwkRXh0ZXJRdWFsKQ0KI2NoZWNrIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIG9yZGluYWwgdmFyaWFibGUNCnRhYmxlKGFsbCRFeHRlclF1YWwpDQpgYGANCnEuIEV4dGVyQ29uZDogRXZhbHVhdGVzIHRoZSBwcmVzZW50IGNvbmRpdGlvbiBvZiB0aGUgbWF0ZXJpYWwgb24gdGhlIGV4dGVyaW9yDQoJCQ0KICAgICAgIEV4CUV4Y2VsbGVudA0KICAgICAgIEdkCUdvb2QNCiAgICAgICBUQQlBdmVyYWdlL1R5cGljYWwNCiAgICAgICBGYQlGYWlyDQogICAgICAgUG8JUG9vcg0KICAgICAgIA0KYGBge3J9DQojY29udmVydCB0byBvcmRpbmFsDQp2YWx1ZXM9YygiUG8iPTAsIkZhIj0xLCJUQSI9MiwiR2QiPTMsIkV4Ij00KQ0KYWxsJEV4dGVyQ29uZD1hcy5pbnRlZ2VyKHJldmFsdWUoYWxsJEV4dGVyQ29uZCwgdmFsdWVzKSkNCmNsYXNzKGFsbCRFeHRlckNvbmQpDQojY2hlY2sgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgb3JkaW5hbCB2YXJpYWJsZQ0KdGFibGUoYWxsJEV4dGVyQ29uZCkNCmBgYA0Kci4gWXJTb2xkOiBZZWFyIFNvbGQgKFlZWVkpDQoNCnMuIE1vU29sZDogTW9udGggU29sZCAoTU0pDQoNCmBgYHtyfQ0KI3RoZSBwcmljZXMgb2YgaG91c2VzIHNob3VsZCBiZSBjaGVhcGVyIGluIGVhcmxpZXIgeWVhcnMuDQojY29udmVydCBZclNvbGQgdG8gb3JkaW5hbA0Kc3ByaW50ZigiSXMgZGF0YSB0eXBlIG9mIFlyU29sZCBpbnRlZ2VyOiAlcyIsIGlzLmludGVnZXIoWXJTb2xkKSkNCiNjb252ZXJ0IHRvIGZhY3Rvcg0Kc3ByaW50ZigiSXMgZGF0YSB0eXBlIG9mIE1vU29sZCBpbnRlZ2VyOiAlcyIsIGlzLmludGVnZXIoTW9Tb2xkKSkNCmFsbCRNb1NvbGQ9YXMuZmFjdG9yKGFsbCRNb1NvbGQpDQpjbGFzcyhhbGwkTW9Tb2xkKQ0KYGBgDQp0LiBNU1N1YkNsYXNzOiBJZGVudGlmaWVzIHRoZSB0eXBlIG9mIGR3ZWxsaW5nIGludm9sdmVkIGluIHRoZSBzYWxlLgkNCg0KICAgICAgICAyMAkxLVNUT1JZIDE5NDYgJiBORVdFUiBBTEwgU1RZTEVTDQogICAgICAgIDMwCTEtU1RPUlkgMTk0NSAmIE9MREVSDQogICAgICAgIDQwCTEtU1RPUlkgVy9GSU5JU0hFRCBBVFRJQyBBTEwgQUdFUw0KICAgICAgICA0NQkxLTEvMiBTVE9SWSAtIFVORklOSVNIRUQgQUxMIEFHRVMNCiAgICAgICAgNTAJMS0xLzIgU1RPUlkgRklOSVNIRUQgQUxMIEFHRVMNCiAgICAgICAgNjAJMi1TVE9SWSAxOTQ2ICYgTkVXRVINCiAgICAgICAgNzAJMi1TVE9SWSAxOTQ1ICYgT0xERVINCiAgICAgICAgNzUJMi0xLzIgU1RPUlkgQUxMIEFHRVMNCiAgICAgICAgODAJU1BMSVQgT1IgTVVMVEktTEVWRUwNCiAgICAgICAgODUJU1BMSVQgRk9ZRVINCiAgICAgICAgOTAJRFVQTEVYIC0gQUxMIFNUWUxFUyBBTkQgQUdFUw0KICAgICAgIDEyMAkxLVNUT1JZIFBVRCAoUGxhbm5lZCBVbml0IERldmVsb3BtZW50KSAtIDE5NDYgJiBORVdFUg0KICAgICAgIDE1MAkxLTEvMiBTVE9SWSBQVUQgLSBBTEwgQUdFUw0KICAgICAgIDE2MAkyLVNUT1JZIFBVRCAtIDE5NDYgJiBORVdFUg0KICAgICAgIDE4MAlQVUQgLSBNVUxUSUxFVkVMIC0gSU5DTCBTUExJVCBMRVYvRk9ZRVINCiAgICAgICAxOTAJMiBGQU1JTFkgQ09OVkVSU0lPTiAtIEFMTCBTVFlMRVMgQU5EIEFHRVMNCg0KYGBge3J9DQojY29udmVydCB0byBmYWN0b3INCmFsbCRNU1N1YkNsYXNzPWFzLmZhY3RvcihhbGwkTVNTdWJDbGFzcykNCnN0cihhbGwkTVNTdWJDbGFzcykNCmBgYA0KdS4gTG90U2hhcGU6IEdlbmVyYWwgc2hhcGUgb2YgcHJvcGVydHkNCg0KICAgICAgIFJlZwlSZWd1bGFyCQ0KICAgICAgIElSMQlTbGlnaHRseSBpcnJlZ3VsYXINCiAgICAgICBJUjIJTW9kZXJhdGVseSBJcnJlZ3VsYXINCiAgICAgICBJUjMJSXJyZWd1bGFyDQoNCmBgYHtyfQ0KI2NvbnZlcnQgTG90U2hhcGUgYXMgZmFjdG9yDQp2YWx1ZXM9YygnSVIzJz0wLCAnSVIyJz0xLCAnSVIxJz0yLCAnUmVnJz0zKQ0KYWxsJExvdFNoYXBlPWFzLmludGVnZXIocmV2YWx1ZShhbGwkTG90U2hhcGUsdmFsdWVzKSkNCmNsYXNzKGFsbCRMb3RTaGFwZSkNCiNjaGVjayB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBkYXRhDQp0YWJsZShhbGwkTG90U2hhcGUpDQpgYGANCnYuIExvdENvbmZpZzogTG90IGNvbmZpZ3VyYXRpb24NCg0KICAgICAgIEluc2lkZQlJbnNpZGUgbG90DQogICAgICAgQ29ybmVyCUNvcm5lciBsb3QNCiAgICAgICBDdWxEU2FjCUN1bC1kZS1zYWMNCiAgICAgICBGUjIJRnJvbnRhZ2Ugb24gMiBzaWRlcyBvZiBwcm9wZXJ0eQ0KICAgICAgIEZSMwlGcm9udGFnZSBvbiAzIHNpZGVzIG9mIHByb3BlcnR5DQoNCmBgYHtyfQ0KI2NvbnZlcnQgTG90Q29uZmlnIGFzIGZhY3Rvcg0KYWxsJExvdENvbmZpZz1hcy5mYWN0b3IoYWxsJExvdENvbmZpZykNCmNsYXNzKGFsbCRMb3RDb25maWcpDQpgYGANCg0Kdy5TYWxlQ29uZGl0aW9uOiBDb25kaXRpb24gb2Ygc2FsZQ0KDQogICAgICAgTm9ybWFsCU5vcm1hbCBTYWxlDQogICAgICAgQWJub3JtbAlBYm5vcm1hbCBTYWxlIC0gIHRyYWRlLCBmb3JlY2xvc3VyZSwgc2hvcnQgc2FsZQ0KICAgICAgIEFkakxhbmQJQWRqb2luaW5nIExhbmQgUHVyY2hhc2UNCiAgICAgICBBbGxvY2EJQWxsb2NhdGlvbiAtIHR3byBsaW5rZWQgcHJvcGVydGllcyB3aXRoIHNlcGFyYXRlIGRlZWRzLCB0eXBpY2FsbHkgY29uZG8gd2l0aCBhIGdhcmFnZSB1bml0CQ0KICAgICAgIEZhbWlseQlTYWxlIGJldHdlZW4gZmFtaWx5IG1lbWJlcnMNCiAgICAgICBQYXJ0aWFsCUhvbWUgd2FzIG5vdCBjb21wbGV0ZWQgd2hlbiBsYXN0IGFzc2Vzc2VkIChhc3NvY2lhdGVkIHdpdGggTmV3IEhvbWVzKQ0KDQpgYGB7cn0NCiNjb252ZXJ0IGFzIGZhY3Rvcg0KYWxsJFNhbGVDb25kaXRpb249YXMuZmFjdG9yKGFsbCRTYWxlQ29uZGl0aW9uKQ0KY2xhc3MoYWxsJFNhbGVDb25kaXRpb24pDQpgYGANCg0KDQogICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBDaGVjayB0aGUgbnVtYmVyIG9mIG1pc3NpbmcgZGF0YSBhbmQgc3RydWN0dXJlIG9mIHRoZSBkYXRhICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCg0KYGBge3J9DQojdGFidWxhdGUgdGhlIG51bWJlciBvZiBtaXNzaW5nIHZhbHVlcw0KbWlzc19mcmVxPXNvcnQoY29sU3Vtcyhpcy5uYShhbGwpKSxkZWNyZWFzaW5nPVRSVUUpDQpwcmludChtaXNzX2ZyZXEpDQpzcHJpbnRmKCJUaGVyZSBhcmUgJXMgY29sdW1ucyBvZiBtaXNzaW5nIHZhbHVlcyIsIHN1bShtaXNzX2ZyZXE+MCkpDQoNCiNjaGVjayB0aGUgc3RydWN0dXJlIG9mIHRoZSBkYXRhDQpzdHIoYWxsKQ0KYGBgDQoNCmBgYHtyfQ0KI3NhdmUgZGF0YWZyYW1lIHdpdGggaXRzIGZvcm1hdHRpbmcuDQpzYXZlUkRTKGFsbCxmaWxlPSJhbGxfRFAucmRzIikNCmBgYA0KDQo=